Merge branch 'av/fsmonitor'
authorJunio C Hamano <gitster@pobox.com>
Tue, 21 Nov 2017 05:07:51 +0000 (14:07 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 21 Nov 2017 05:07:51 +0000 (14:07 +0900)
Various fixes to bp/fsmonitor topic.

* av/fsmonitor:
fsmonitor: simplify determining the git worktree under Windows
fsmonitor: store fsmonitor bitmap before splitting index
fsmonitor: read from getcwd(), not the PWD environment variable
fsmonitor: delay updating state until after split index is merged
fsmonitor: document GIT_TRACE_FSMONITOR
fsmonitor: don't bother pretty-printing JSON from watchman
fsmonitor: set the PWD to the top of the working tree

Documentation/git.txt
cache.h
fsmonitor.c
fsmonitor.h
read-cache.c
t/t7519-status-fsmonitor.sh
t/t7519/fsmonitor-watchman
templates/hooks--fsmonitor-watchman.sample
index 463b0eb0f5c3c8e694a509d3e06aee29056f970d..483a1f35475ea435e5c93121e67ad8085855bfc3 100644 (file)
@@ -595,6 +595,10 @@ into it.
 Unsetting the variable, or setting it to empty, "0" or
 "false" (case insensitive) disables trace messages.
 
+`GIT_TRACE_FSMONITOR`::
+       Enables trace messages for the filesystem monitor extension.
+       See `GIT_TRACE` for available trace output options.
+
 `GIT_TRACE_PACK_ACCESS`::
        Enables trace messages for all accesses to any packs. For each
        access, the pack file name and an offset in the pack is
diff --git a/cache.h b/cache.h
index 7c716812362aa179dc56966aa3a80e597a3a13b2..f684c7933ba38041961f210425f31d2976190054 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -348,6 +348,7 @@ struct index_state {
        unsigned char sha1[20];
        struct untracked_cache *untracked;
        uint64_t fsmonitor_last_update;
+       struct ewah_bitmap *fsmonitor_dirty;
 };
 
 extern struct index_state the_index;
index 7c1540c05493f9437e33f4dd0ec18bae0b5f808c..0af7c4edba37fd9f6a8cee83cd2715c3fa08b488 100644 (file)
@@ -26,7 +26,6 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
        uint32_t hdr_version;
        uint32_t ewah_size;
        struct ewah_bitmap *fsmonitor_dirty;
-       int i;
        int ret;
 
        if (sz < sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint32_t))
@@ -49,31 +48,25 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
                ewah_free(fsmonitor_dirty);
                return error("failed to parse ewah bitmap reading fsmonitor index extension");
        }
-
-       if (git_config_get_fsmonitor()) {
-               /* Mark all entries valid */
-               for (i = 0; i < istate->cache_nr; i++)
-                       istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID;
-
-               /* Mark all previously saved entries as dirty */
-               ewah_each_bit(fsmonitor_dirty, fsmonitor_ewah_callback, istate);
-
-               /* Now mark the untracked cache for fsmonitor usage */
-               if (istate->untracked)
-                       istate->untracked->use_fsmonitor = 1;
-       }
-       ewah_free(fsmonitor_dirty);
+       istate->fsmonitor_dirty = fsmonitor_dirty;
 
        trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful");
        return 0;
 }
 
+void fill_fsmonitor_bitmap(struct index_state *istate)
+{
+       int i;
+       istate->fsmonitor_dirty = ewah_new();
+       for (i = 0; i < istate->cache_nr; i++)
+               if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID))
+                       ewah_set(istate->fsmonitor_dirty, i);
+}
+
 void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
 {
        uint32_t hdr_version;
        uint64_t tm;
-       struct ewah_bitmap *bitmap;
-       int i;
        uint32_t ewah_start;
        uint32_t ewah_size = 0;
        int fixup = 0;
@@ -87,12 +80,9 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
        strbuf_add(sb, &ewah_size, sizeof(uint32_t)); /* we'll fix this up later */
 
        ewah_start = sb->len;
-       bitmap = ewah_new();
-       for (i = 0; i < istate->cache_nr; i++)
-               if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID))
-                       ewah_set(bitmap, i);
-       ewah_serialize_strbuf(bitmap, sb);
-       ewah_free(bitmap);
+       ewah_serialize_strbuf(istate->fsmonitor_dirty, sb);
+       ewah_free(istate->fsmonitor_dirty);
+       istate->fsmonitor_dirty = NULL;
 
        /* fix up size field */
        put_be32(&ewah_size, sb->len - ewah_start);
@@ -121,6 +111,7 @@ static int query_fsmonitor(int version, uint64_t last_update, struct strbuf *que
        argv[3] = NULL;
        cp.argv = argv;
        cp.use_shell = 1;
+       cp.dir = get_git_work_tree();
 
        return capture_command(&cp, query_result, 1024);
 }
@@ -238,7 +229,29 @@ void remove_fsmonitor(struct index_state *istate)
 
 void tweak_fsmonitor(struct index_state *istate)
 {
-       switch (git_config_get_fsmonitor()) {
+       int i;
+       int fsmonitor_enabled = git_config_get_fsmonitor();
+
+       if (istate->fsmonitor_dirty) {
+               if (fsmonitor_enabled) {
+                       /* Mark all entries valid */
+                       for (i = 0; i < istate->cache_nr; i++) {
+                               istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID;
+                       }
+
+                       /* Mark all previously saved entries as dirty */
+                       ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate);
+
+                       /* Now mark the untracked cache for fsmonitor usage */
+                       if (istate->untracked)
+                               istate->untracked->use_fsmonitor = 1;
+               }
+
+               ewah_free(istate->fsmonitor_dirty);
+               istate->fsmonitor_dirty = NULL;
+       }
+
+       switch (fsmonitor_enabled) {
        case -1: /* keep: do nothing */
                break;
        case 0: /* false */
index 0de644e01aaea7e6082dc5b63015d498f324d271..cd3cc0ccf228c9d601621685042d51368a71c707 100644 (file)
@@ -10,7 +10,14 @@ extern struct trace_key trace_fsmonitor;
 extern int read_fsmonitor_extension(struct index_state *istate, const void *data, unsigned long sz);
 
 /*
- * Write the CE_FSMONITOR_VALID state into the fsmonitor index extension.
+ * Fill the fsmonitor_dirty ewah bits with their state from the index,
+ * before it is split during writing.
+ */
+extern void fill_fsmonitor_bitmap(struct index_state *istate);
+
+/*
+ * Write the CE_FSMONITOR_VALID state into the fsmonitor index
+ * extension.  Reads from the fsmonitor_dirty ewah in the index.
  */
 extern void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate);
 
index 87e88b2642f22a0db1652435ff5ad63f3c240010..fbb4967c81976825e7d2c52da91391c6574c4b71 100644 (file)
@@ -2535,6 +2535,9 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
        int new_shared_index, ret;
        struct split_index *si = istate->split_index;
 
+       if (istate->fsmonitor_last_update)
+               fill_fsmonitor_bitmap(istate);
+
        if (!si || alternate_index_output ||
            (istate->cache_changed & ~EXTMASK)) {
                if (si)
index c6df85af5ee2d401d69a4eeabd3a48dc73030963..eb2d13bbcf8abefd7af2be6f9cb3bf97e389ab15 100755 (executable)
@@ -301,4 +301,17 @@ do
        done
 done
 
+# test that splitting the index dosn't interfere
+test_expect_success 'splitting the index results in the same state' '
+       write_integration_script &&
+       dirty_repo &&
+       git update-index --fsmonitor  &&
+       git ls-files -f >expect &&
+       test-dump-fsmonitor >&2 && echo &&
+       git update-index --fsmonitor --split-index &&
+       test-dump-fsmonitor >&2 && echo &&
+       git ls-files -f >actual &&
+       test_cmp expect actual
+'
+
 test_done
index a3e30bf54fc2f1bf4fbb3ce48fa13e33b2e6b346..5514edcf68be8020ca94e8c51b9c9f2b3102bd09 100755 (executable)
@@ -29,19 +29,13 @@ if ($version == 1) {
            "Falling back to scanning...\n";
 }
 
-# Convert unix style paths to escaped Windows style paths when running
-# in Windows command prompt
-
-my $system = `uname -s`;
-$system =~ s/[\r\n]+//g;
 my $git_work_tree;
-
-if ($system =~ m/^MSYS_NT/ || $system =~ m/^MINGW/) {
-       $git_work_tree = `cygpath -aw "\$PWD"`;
-       $git_work_tree =~ s/[\r\n]+//g;
-       $git_work_tree =~ s,\\,/,g;
+if ($^O =~ 'msys' || $^O =~ 'cygwin') {
+       $git_work_tree = Win32::GetCwd();
+       $git_work_tree =~ tr/\\/\//;
 } else {
-       $git_work_tree = $ENV{'PWD'};
+       require Cwd;
+       $git_work_tree = Cwd::cwd();
 }
 
 my $retry = 1;
index 9eba8a740933dfa77d7155aca2ba1979e9d0fb68..e673bb3980f3c286291809e05f80873852bc3e9c 100755 (executable)
@@ -28,19 +28,13 @@ if ($version == 1) {
            "Falling back to scanning...\n";
 }
 
-# Convert unix style paths to escaped Windows style paths when running
-# in Windows command prompt
-
-my $system = `uname -s`;
-$system =~ s/[\r\n]+//g;
 my $git_work_tree;
-
-if ($system =~ m/^MSYS_NT/ || $system =~ m/^MINGW/) {
-       $git_work_tree = `cygpath -aw "\$PWD"`;
-       $git_work_tree =~ s/[\r\n]+//g;
-       $git_work_tree =~ s,\\,/,g;
+if ($^O =~ 'msys' || $^O =~ 'cygwin') {
+       $git_work_tree = Win32::GetCwd();
+       $git_work_tree =~ tr/\\/\//;
 } else {
-       $git_work_tree = $ENV{'PWD'};
+       require Cwd;
+       $git_work_tree = Cwd::cwd();
 }
 
 my $retry = 1;
@@ -49,7 +43,7 @@ launch_watchman();
 
 sub launch_watchman {
 
-       my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j')
+       my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
            or die "open2() failed: $!\n" .
            "Falling back to scanning...\n";