[PATCH 20/24] update-index: test the system before enabling untracked cache

2015-03-08 Thread Nguyễn Thái Ngọc Duy
Helped-by: Eric Sunshine 
Helped-by: Junio C Hamano 
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 Documentation/git-update-index.txt |   6 ++
 builtin/update-index.c | 168 +
 2 files changed, 174 insertions(+)

diff --git a/Documentation/git-update-index.txt 
b/Documentation/git-update-index.txt
index f9a35cd..ed32bae 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -180,6 +180,12 @@ may not support it yet.
system must change `st_mtime` field of a directory if files
are added or deleted in that directory.
 
+--force-untracked-cache::
+   For safety, `--untracked-cache` performs tests on the working
+   directory to make sure untracked cache can be used. These
+   tests can take a few seconds. `--force-untracked-cache` can be
+   used to skip the tests.
+
 \--::
Do not interpret any more arguments as options.
 
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 3d2dedd..f5f6689 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -32,6 +32,7 @@ static int mark_valid_only;
 static int mark_skip_worktree_only;
 #define MARK_FLAG 1
 #define UNMARK_FLAG 2
+static struct strbuf mtime_dir = STRBUF_INIT;
 
 __attribute__((format (printf, 1, 2)))
 static void report(const char *fmt, ...)
@@ -47,6 +48,166 @@ static void report(const char *fmt, ...)
va_end(vp);
 }
 
+static void remove_test_directory(void)
+{
+   if (mtime_dir.len)
+   remove_dir_recursively(&mtime_dir, 0);
+}
+
+static const char *get_mtime_path(const char *path)
+{
+   static struct strbuf sb = STRBUF_INIT;
+   strbuf_reset(&sb);
+   strbuf_addf(&sb, "%s/%s", mtime_dir.buf, path);
+   return sb.buf;
+}
+
+static void xmkdir(const char *path)
+{
+   path = get_mtime_path(path);
+   if (mkdir(path, 0700))
+   die_errno(_("failed to create directory %s"), path);
+}
+
+static int xstat_mtime_dir(struct stat *st)
+{
+   if (stat(mtime_dir.buf, st))
+   die_errno(_("failed to stat %s"), mtime_dir.buf);
+   return 0;
+}
+
+static int create_file(const char *path)
+{
+   int fd;
+   path = get_mtime_path(path);
+   fd = open(path, O_CREAT | O_RDWR, 0644);
+   if (fd < 0)
+   die_errno(_("failed to create file %s"), path);
+   return fd;
+}
+
+static void xunlink(const char *path)
+{
+   path = get_mtime_path(path);
+   if (unlink(path))
+   die_errno(_("failed to delete file %s"), path);
+}
+
+static void xrmdir(const char *path)
+{
+   path = get_mtime_path(path);
+   if (rmdir(path))
+   die_errno(_("failed to delete directory %s"), path);
+}
+
+static void avoid_racy(void)
+{
+   /*
+* not use if we could usleep(10) if USE_NSEC is defined. The
+* field nsec could be there, but the OS could choose to
+* ignore it?
+*/
+   sleep(1);
+}
+
+static int test_if_untracked_cache_is_supported(void)
+{
+   struct stat st;
+   struct stat_data base;
+   int fd, ret = 0;
+
+   strbuf_addstr(&mtime_dir, "mtime-test-XX");
+   if (!mkdtemp(mtime_dir.buf))
+   die_errno("Could not make temporary directory");
+
+   fprintf(stderr, _("Testing "));
+   atexit(remove_test_directory);
+   xstat_mtime_dir(&st);
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   fd = create_file("newfile");
+   xstat_mtime_dir(&st);
+   if (!match_stat_data(&base, &st)) {
+   close(fd);
+   fputc('\n', stderr);
+   fprintf_ln(stderr,_("directory stat info does not "
+   "change after adding a new file"));
+   goto done;
+   }
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   xmkdir("new-dir");
+   xstat_mtime_dir(&st);
+   if (!match_stat_data(&base, &st)) {
+   close(fd);
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info does not change "
+"after adding a new directory"));
+   goto done;
+   }
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   write_or_die(fd, "data", 4);
+   close(fd);
+   xstat_mtime_dir(&st);
+   if (match_stat_data(&base, &st)) {
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info changes "
+"after updating a file"));
+   goto done;
+   }
+   fputc('.', stderr);
+
+   avoid_racy();
+   close(create_file("new-dir/new"));
+   xstat_mtime_dir(&st);
+   if (match_stat_data(&base, &st)) {
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info changes a

[PATCH 20/24] update-index: test the system before enabling untracked cache

2015-02-08 Thread Nguyễn Thái Ngọc Duy
Helped-by: Eric Sunshine 
Helped-by: Junio C Hamano 
Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 Documentation/git-update-index.txt |   6 ++
 builtin/update-index.c | 168 +
 2 files changed, 174 insertions(+)

diff --git a/Documentation/git-update-index.txt 
b/Documentation/git-update-index.txt
index f9a35cd..ed32bae 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -180,6 +180,12 @@ may not support it yet.
system must change `st_mtime` field of a directory if files
are added or deleted in that directory.
 
+--force-untracked-cache::
+   For safety, `--untracked-cache` performs tests on the working
+   directory to make sure untracked cache can be used. These
+   tests can take a few seconds. `--force-untracked-cache` can be
+   used to skip the tests.
+
 \--::
Do not interpret any more arguments as options.
 
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 3d2dedd..f5f6689 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -32,6 +32,7 @@ static int mark_valid_only;
 static int mark_skip_worktree_only;
 #define MARK_FLAG 1
 #define UNMARK_FLAG 2
+static struct strbuf mtime_dir = STRBUF_INIT;
 
 __attribute__((format (printf, 1, 2)))
 static void report(const char *fmt, ...)
@@ -47,6 +48,166 @@ static void report(const char *fmt, ...)
va_end(vp);
 }
 
+static void remove_test_directory(void)
+{
+   if (mtime_dir.len)
+   remove_dir_recursively(&mtime_dir, 0);
+}
+
+static const char *get_mtime_path(const char *path)
+{
+   static struct strbuf sb = STRBUF_INIT;
+   strbuf_reset(&sb);
+   strbuf_addf(&sb, "%s/%s", mtime_dir.buf, path);
+   return sb.buf;
+}
+
+static void xmkdir(const char *path)
+{
+   path = get_mtime_path(path);
+   if (mkdir(path, 0700))
+   die_errno(_("failed to create directory %s"), path);
+}
+
+static int xstat_mtime_dir(struct stat *st)
+{
+   if (stat(mtime_dir.buf, st))
+   die_errno(_("failed to stat %s"), mtime_dir.buf);
+   return 0;
+}
+
+static int create_file(const char *path)
+{
+   int fd;
+   path = get_mtime_path(path);
+   fd = open(path, O_CREAT | O_RDWR, 0644);
+   if (fd < 0)
+   die_errno(_("failed to create file %s"), path);
+   return fd;
+}
+
+static void xunlink(const char *path)
+{
+   path = get_mtime_path(path);
+   if (unlink(path))
+   die_errno(_("failed to delete file %s"), path);
+}
+
+static void xrmdir(const char *path)
+{
+   path = get_mtime_path(path);
+   if (rmdir(path))
+   die_errno(_("failed to delete directory %s"), path);
+}
+
+static void avoid_racy(void)
+{
+   /*
+* not use if we could usleep(10) if USE_NSEC is defined. The
+* field nsec could be there, but the OS could choose to
+* ignore it?
+*/
+   sleep(1);
+}
+
+static int test_if_untracked_cache_is_supported(void)
+{
+   struct stat st;
+   struct stat_data base;
+   int fd, ret = 0;
+
+   strbuf_addstr(&mtime_dir, "mtime-test-XX");
+   if (!mkdtemp(mtime_dir.buf))
+   die_errno("Could not make temporary directory");
+
+   fprintf(stderr, _("Testing "));
+   atexit(remove_test_directory);
+   xstat_mtime_dir(&st);
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   fd = create_file("newfile");
+   xstat_mtime_dir(&st);
+   if (!match_stat_data(&base, &st)) {
+   close(fd);
+   fputc('\n', stderr);
+   fprintf_ln(stderr,_("directory stat info does not "
+   "change after adding a new file"));
+   goto done;
+   }
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   xmkdir("new-dir");
+   xstat_mtime_dir(&st);
+   if (!match_stat_data(&base, &st)) {
+   close(fd);
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info does not change "
+"after adding a new directory"));
+   goto done;
+   }
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   write_or_die(fd, "data", 4);
+   close(fd);
+   xstat_mtime_dir(&st);
+   if (match_stat_data(&base, &st)) {
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info changes "
+"after updating a file"));
+   goto done;
+   }
+   fputc('.', stderr);
+
+   avoid_racy();
+   close(create_file("new-dir/new"));
+   xstat_mtime_dir(&st);
+   if (match_stat_data(&base, &st)) {
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info changes after "
+   

Re: [PATCH 20/24] update-index: test the system before enabling untracked cache

2015-01-23 Thread Duy Nguyen
On Fri, Jan 23, 2015 at 1:49 AM, Junio C Hamano  wrote:
> I am not (yet) enthused by the intrusiveness of the overall series, though.

I think the gain justifies the series' complexity. Although I don't
mind redoing the whole series if we find a better way.
-- 
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 20/24] update-index: test the system before enabling untracked cache

2015-01-22 Thread Junio C Hamano
Duy Nguyen  writes:

> On Wed, Jan 21, 2015 at 10:51:02AM -0800, Junio C Hamano wrote:
>> >> It appears that this hijacks a fixed name dir-mtime-test at the root
>> >> level of every project managed by Git.  Is that intended?
>> >
>> > I did think about filename clash, but I chose a fixed name anyway for
>> > simplicity, otherwise we would need to reconstruct paths
>> > "dir-mtime-test/..." in many places.
>> 
>> If you stuff the name of test directory (default "dir-mtime-test")
>> in a strbuf and formulate test paths by chomping to the original and
>> then appending "/..." at the end, like your remove_test_directory()
>> already does, wouldn't that be sufficient?
>
> It looks actually good. How about this on top?

Yeah, looks cleaner.  I am not (yet) enthused by the intrusiveness
of the overall series, though.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 20/24] update-index: test the system before enabling untracked cache

2015-01-22 Thread Duy Nguyen
On Wed, Jan 21, 2015 at 10:51:02AM -0800, Junio C Hamano wrote:
> >> It appears that this hijacks a fixed name dir-mtime-test at the root
> >> level of every project managed by Git.  Is that intended?
> >
> > I did think about filename clash, but I chose a fixed name anyway for
> > simplicity, otherwise we would need to reconstruct paths
> > "dir-mtime-test/..." in many places.
> 
> If you stuff the name of test directory (default "dir-mtime-test")
> in a strbuf and formulate test paths by chomping to the original and
> then appending "/..." at the end, like your remove_test_directory()
> already does, wouldn't that be sufficient?

It looks actually good. How about this on top?

-- 8< --
diff --git a/builtin/update-index.c b/builtin/update-index.c
index f23ec83..f5f6689 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -32,6 +32,7 @@ static int mark_valid_only;
 static int mark_skip_worktree_only;
 #define MARK_FLAG 1
 #define UNMARK_FLAG 2
+static struct strbuf mtime_dir = STRBUF_INIT;
 
 __attribute__((format (printf, 1, 2)))
 static void report(const char *fmt, ...)
@@ -49,28 +50,37 @@ static void report(const char *fmt, ...)
 
 static void remove_test_directory(void)
 {
-   struct strbuf sb = STRBUF_INIT;
-   strbuf_addstr(&sb, "dir-mtime-test");
-   remove_dir_recursively(&sb, 0);
-   strbuf_release(&sb);
+   if (mtime_dir.len)
+   remove_dir_recursively(&mtime_dir, 0);
+}
+
+static const char *get_mtime_path(const char *path)
+{
+   static struct strbuf sb = STRBUF_INIT;
+   strbuf_reset(&sb);
+   strbuf_addf(&sb, "%s/%s", mtime_dir.buf, path);
+   return sb.buf;
 }
 
 static void xmkdir(const char *path)
 {
+   path = get_mtime_path(path);
if (mkdir(path, 0700))
die_errno(_("failed to create directory %s"), path);
 }
 
-static int xstat(const char *path, struct stat *st)
+static int xstat_mtime_dir(struct stat *st)
 {
-   if (stat(path, st))
-   die_errno(_("failed to stat %s"), path);
+   if (stat(mtime_dir.buf, st))
+   die_errno(_("failed to stat %s"), mtime_dir.buf);
return 0;
 }
 
 static int create_file(const char *path)
 {
-   int fd = open(path, O_CREAT | O_RDWR, 0644);
+   int fd;
+   path = get_mtime_path(path);
+   fd = open(path, O_CREAT | O_RDWR, 0644);
if (fd < 0)
die_errno(_("failed to create file %s"), path);
return fd;
@@ -78,12 +88,14 @@ static int create_file(const char *path)
 
 static void xunlink(const char *path)
 {
+   path = get_mtime_path(path);
if (unlink(path))
die_errno(_("failed to delete file %s"), path);
 }
 
 static void xrmdir(const char *path)
 {
+   path = get_mtime_path(path);
if (rmdir(path))
die_errno(_("failed to delete directory %s"), path);
 }
@@ -102,37 +114,40 @@ static int test_if_untracked_cache_is_supported(void)
 {
struct stat st;
struct stat_data base;
-   int fd;
+   int fd, ret = 0;
+
+   strbuf_addstr(&mtime_dir, "mtime-test-XX");
+   if (!mkdtemp(mtime_dir.buf))
+   die_errno("Could not make temporary directory");
 
fprintf(stderr, _("Testing "));
-   xmkdir("dir-mtime-test");
atexit(remove_test_directory);
-   xstat("dir-mtime-test", &st);
+   xstat_mtime_dir(&st);
fill_stat_data(&base, &st);
fputc('.', stderr);
 
avoid_racy();
-   fd = create_file("dir-mtime-test/newfile");
-   xstat("dir-mtime-test", &st);
+   fd = create_file("newfile");
+   xstat_mtime_dir(&st);
if (!match_stat_data(&base, &st)) {
close(fd);
fputc('\n', stderr);
fprintf_ln(stderr,_("directory stat info does not "
"change after adding a new file"));
-   return 0;
+   goto done;
}
fill_stat_data(&base, &st);
fputc('.', stderr);
 
avoid_racy();
-   xmkdir("dir-mtime-test/new-dir");
-   xstat("dir-mtime-test", &st);
+   xmkdir("new-dir");
+   xstat_mtime_dir(&st);
if (!match_stat_data(&base, &st)) {
close(fd);
fputc('\n', stderr);
fprintf_ln(stderr, _("directory stat info does not change "
 "after adding a new directory"));
-   return 0;
+   goto done;
}
fill_stat_data(&base, &st);
fputc('.', stderr);
@@ -140,52 +155,57 @@ static int test_if_untracked_cache_is_supported(void)
avoid_racy();
write_or_die(fd, "data", 4);
close(fd);
-   xstat("dir-mtime-test", &st);
+   xstat_mtime_dir(&st);
if (match_stat_data(&base, &st)) {
fputc('\n', stderr);
fprintf_ln(stderr, _("directory stat info changes "
 "after updating a file"));
-  

Re: [PATCH 20/24] update-index: test the system before enabling untracked cache

2015-01-21 Thread Junio C Hamano
Duy Nguyen  writes:

> On Wed, Jan 21, 2015 at 3:32 PM, Junio C Hamano  wrote:
>> Nguyễn Thái Ngọc Duy   writes:
>>
>>> Helped-by: Eric Sunshine 
>>> Signed-off-by: Nguyễn Thái Ngọc Duy 
>>> Signed-off-by: Junio C Hamano 
>>> ---
>>
>> It appears that this hijacks a fixed name dir-mtime-test at the root
>> level of every project managed by Git.  Is that intended?
>
> I did think about filename clash, but I chose a fixed name anyway for
> simplicity, otherwise we would need to reconstruct paths
> "dir-mtime-test/..." in many places.

If you stuff the name of test directory (default "dir-mtime-test")
in a strbuf and formulate test paths by chomping to the original and
then appending "/..." at the end, like your remove_test_directory()
already does, wouldn't that be sufficient?

>> Shouldn't --use-untracked-cache option require the working tree
>> (i.e. die in a bare repository)?
>
> setup_work_tree() takes care of that

OK, thanks.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 20/24] update-index: test the system before enabling untracked cache

2015-01-21 Thread Duy Nguyen
On Wed, Jan 21, 2015 at 3:32 PM, Junio C Hamano  wrote:
> Nguyễn Thái Ngọc Duy   writes:
>
>> Helped-by: Eric Sunshine 
>> Signed-off-by: Nguyễn Thái Ngọc Duy 
>> Signed-off-by: Junio C Hamano 
>> ---
>
> It appears that this hijacks a fixed name dir-mtime-test at the root
> level of every project managed by Git.  Is that intended?

I did think about filename clash, but I chose a fixed name anyway for
simplicity, otherwise we would need to reconstruct paths
"dir-mtime-test/..." in many places.

> Shouldn't --use-untracked-cache option require the working tree
> (i.e. die in a bare repository)?

setup_work_tree() takes care of that

> ~/w/git $ git init --bare foo
Khởi tạo trống rỗng kho Git trong /home/pclouds/w/git/foo/
> ~/w/git $ cd foo/
> ~/w/git/foo $ ../git update-index --untracked-cache
fatal: This operation must be run in a work tree
-- 
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 20/24] update-index: test the system before enabling untracked cache

2015-01-21 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy   writes:

> Helped-by: Eric Sunshine 
> Signed-off-by: Nguyễn Thái Ngọc Duy 
> Signed-off-by: Junio C Hamano 
> ---

It appears that this hijacks a fixed name dir-mtime-test at the root
level of every project managed by Git.  Is that intended?

Shouldn't --use-untracked-cache option require the working tree
(i.e. die in a bare repository)?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 20/24] update-index: test the system before enabling untracked cache

2015-01-20 Thread Nguyễn Thái Ngọc Duy
Helped-by: Eric Sunshine 
Signed-off-by: Nguyễn Thái Ngọc Duy 
Signed-off-by: Junio C Hamano 
---
 Documentation/git-update-index.txt |   6 ++
 builtin/update-index.c | 148 +
 2 files changed, 154 insertions(+)

diff --git a/Documentation/git-update-index.txt 
b/Documentation/git-update-index.txt
index f9a35cd..ed32bae 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -180,6 +180,12 @@ may not support it yet.
system must change `st_mtime` field of a directory if files
are added or deleted in that directory.
 
+--force-untracked-cache::
+   For safety, `--untracked-cache` performs tests on the working
+   directory to make sure untracked cache can be used. These
+   tests can take a few seconds. `--force-untracked-cache` can be
+   used to skip the tests.
+
 \--::
Do not interpret any more arguments as options.
 
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 3d2dedd..f23ec83 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -47,6 +47,147 @@ static void report(const char *fmt, ...)
va_end(vp);
 }
 
+static void remove_test_directory(void)
+{
+   struct strbuf sb = STRBUF_INIT;
+   strbuf_addstr(&sb, "dir-mtime-test");
+   remove_dir_recursively(&sb, 0);
+   strbuf_release(&sb);
+}
+
+static void xmkdir(const char *path)
+{
+   if (mkdir(path, 0700))
+   die_errno(_("failed to create directory %s"), path);
+}
+
+static int xstat(const char *path, struct stat *st)
+{
+   if (stat(path, st))
+   die_errno(_("failed to stat %s"), path);
+   return 0;
+}
+
+static int create_file(const char *path)
+{
+   int fd = open(path, O_CREAT | O_RDWR, 0644);
+   if (fd < 0)
+   die_errno(_("failed to create file %s"), path);
+   return fd;
+}
+
+static void xunlink(const char *path)
+{
+   if (unlink(path))
+   die_errno(_("failed to delete file %s"), path);
+}
+
+static void xrmdir(const char *path)
+{
+   if (rmdir(path))
+   die_errno(_("failed to delete directory %s"), path);
+}
+
+static void avoid_racy(void)
+{
+   /*
+* not use if we could usleep(10) if USE_NSEC is defined. The
+* field nsec could be there, but the OS could choose to
+* ignore it?
+*/
+   sleep(1);
+}
+
+static int test_if_untracked_cache_is_supported(void)
+{
+   struct stat st;
+   struct stat_data base;
+   int fd;
+
+   fprintf(stderr, _("Testing "));
+   xmkdir("dir-mtime-test");
+   atexit(remove_test_directory);
+   xstat("dir-mtime-test", &st);
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   fd = create_file("dir-mtime-test/newfile");
+   xstat("dir-mtime-test", &st);
+   if (!match_stat_data(&base, &st)) {
+   close(fd);
+   fputc('\n', stderr);
+   fprintf_ln(stderr,_("directory stat info does not "
+   "change after adding a new file"));
+   return 0;
+   }
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   xmkdir("dir-mtime-test/new-dir");
+   xstat("dir-mtime-test", &st);
+   if (!match_stat_data(&base, &st)) {
+   close(fd);
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info does not change "
+"after adding a new directory"));
+   return 0;
+   }
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   write_or_die(fd, "data", 4);
+   close(fd);
+   xstat("dir-mtime-test", &st);
+   if (match_stat_data(&base, &st)) {
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info changes "
+"after updating a file"));
+   return 0;
+   }
+   fputc('.', stderr);
+
+   avoid_racy();
+   close(create_file("dir-mtime-test/new-dir/new"));
+   xstat("dir-mtime-test", &st);
+   if (match_stat_data(&base, &st)) {
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info changes after "
+"adding a file inside subdirectory"));
+   return 0;
+   }
+   fputc('.', stderr);
+
+   avoid_racy();
+   xunlink("dir-mtime-test/newfile");
+   xstat("dir-mtime-test", &st);
+   if (!match_stat_data(&base, &st)) {
+   fputc('\n', stderr);
+   fprintf_ln(stderr, _("directory stat info does not "
+"change after deleting a file"));
+   return 0;
+   }
+   fill_stat_data(&base, &st);
+   fputc('.', stderr);
+
+   avoid_racy();
+   xunlink("dir-mtime-test/new-dir/new");
+