---
 builtin/update-index.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 144 insertions(+)

diff --git a/builtin/update-index.c b/builtin/update-index.c
index 003e28e..f18076b 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -46,6 +46,145 @@ static void report(const char *fmt, ...)
        va_end(vp);
 }
 
+static void remove_test_directory(void)
+{
+       struct strbuf sb = STRBUF_INIT;
+       strbuf_addstr(&sb, git_path("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(git_path("dir-mtime-test"));
+       atexit(remove_test_directory);
+       xstat(git_path("dir-mtime-test"), &st);
+       fill_stat_data(&base, &st);
+       fputc('.', stderr);
+
+       avoid_racy();
+       fd = create_file(git_path("dir-mtime-test/newfile"));
+       xstat(git_path("dir-mtime-test"), &st);
+       if (!match_stat_data(&base, &st)) {
+               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(git_path("dir-mtime-test/new-dir"));
+       xstat(git_path("dir-mtime-test"), &st);
+       if (!match_stat_data(&base, &st)) {
+               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(git_path("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(git_path("dir-mtime-test/new-dir/new")));
+       xstat(git_path("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(git_path("dir-mtime-test/newfile"));
+       xstat(git_path("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(git_path("dir-mtime-test/new-dir/new"));
+       xrmdir(git_path("dir-mtime-test/new-dir"));
+       xstat(git_path("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 directory"));
+               return 0;
+       }
+
+       xrmdir(git_path("dir-mtime-test"));
+       fprintf_ln(stderr, _(" OK"));
+       return 1;
+}
+
 static int mark_ce_flags(const char *path, int flag, int mark)
 {
        int namelen = strlen(path);
@@ -823,6 +962,8 @@ int cmd_update_index(int argc, const char **argv, const 
char *prefix)
                        resolve_undo_clear_callback},
                OPT_INTEGER(0, "index-version", &preferred_index_format,
                        N_("write index in this format")),
+               OPT_SET_INT(0, "force-untracked-cache", &untracked_cache,
+                           N_("enable untracked cache without testing the 
filesystem"), 2),
                OPT_BOOL(0, "untracked-cache", &untracked_cache,
                        N_("enable/disable untracked cache")),
                OPT_END()
@@ -921,6 +1062,9 @@ int cmd_update_index(int argc, const char **argv, const 
char *prefix)
        if (untracked_cache > 0) {
                struct untracked_cache *uc;
 
+               if (untracked_cache < 2 &&
+                   !test_if_untracked_cache_is_supported())
+                       return 1;
                uc = xcalloc(1, sizeof(*uc));
                uc->exclude_per_dir = ".gitignore";
                /* should be the same flags used by git-status */
-- 
1.9.1.346.ga2b5940

--
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

Reply via email to