]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'us/unpack-trees-fsmonitor'
authorJunio C Hamano <gitster@pobox.com>
Thu, 5 Dec 2019 20:52:48 +0000 (12:52 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 5 Dec 2019 20:52:48 +0000 (12:52 -0800)
Users of oneway_merge() (like "reset --hard") learned to take
advantage of fsmonitor to avoid unnecessary lstat(2) calls.

* us/unpack-trees-fsmonitor:
  unpack-trees: skip stat on fsmonitor-valid files

fsmonitor.c
t/t7519-status-fsmonitor.sh
unpack-trees.c

index 0477500b392b2baee699b51f2afa39381e66504d..868cca01e250896054b1f7025c7180c87ab1b88d 100644 (file)
@@ -191,13 +191,26 @@ void refresh_fsmonitor(struct index_state *istate)
                }
                if (bol < query_result.len)
                        fsmonitor_refresh_callback(istate, buf + bol);
+
+               /* Now mark the untracked cache for fsmonitor usage */
+               if (istate->untracked)
+                       istate->untracked->use_fsmonitor = 1;
        } else {
+
+               /* We only want to run the post index changed hook if we've actually changed entries, so keep track
+                * if we actually changed entries or not */
+               int is_cache_changed = 0;
                /* Mark all entries invalid */
-               for (i = 0; i < istate->cache_nr; i++)
-                       istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID;
+               for (i = 0; i < istate->cache_nr; i++) {
+                       if (istate->cache[i]->ce_flags & CE_FSMONITOR_VALID) {
+                               is_cache_changed = 1;
+                               istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID;
+                       }
+               }
 
                /* If we're going to check every file, ensure we save the results */
-               istate->cache_changed |= FSMONITOR_CHANGED;
+               if (is_cache_changed)
+                       istate->cache_changed |= FSMONITOR_CHANGED;
 
                if (istate->untracked)
                        istate->untracked->use_fsmonitor = 0;
@@ -259,9 +272,7 @@ void tweak_fsmonitor(struct index_state *istate)
                                    (uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr);
                        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;
+                       refresh_fsmonitor(istate);
                }
 
                ewah_free(istate->fsmonitor_dirty);
index 1e47ed2ca27a401bfc177e69ee0966c9b4ac1f09..cf0fda2d5aa534d3ed4f64be48a52201535d854f 100755 (executable)
@@ -106,6 +106,8 @@ EOF
 
 # test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
 test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
+       write_script .git/hooks/fsmonitor-test<<-\EOF &&
+       EOF
        git update-index --fsmonitor &&
        git update-index --fsmonitor-valid dir1/modified &&
        git update-index --fsmonitor-valid dir2/modified &&
@@ -164,6 +166,8 @@ EOF
 
 # test that newly added files are marked valid
 test_expect_success 'newly added files are marked valid' '
+       write_script .git/hooks/fsmonitor-test<<-\EOF &&
+       EOF
        git add new &&
        git add dir1/new &&
        git add dir2/new &&
@@ -218,11 +222,12 @@ test_expect_success '*only* files returned by the integration script get flagged
 # Ensure commands that call refresh_index() to move the index back in time
 # properly invalidate the fsmonitor cache
 test_expect_success 'refresh_index() invalidates fsmonitor cache' '
-       write_script .git/hooks/fsmonitor-test<<-\EOF &&
-       EOF
        clean_repo &&
        dirty_repo &&
+       write_integration_script &&
        git add . &&
+       write_script .git/hooks/fsmonitor-test<<-\EOF &&
+       EOF
        git commit -m "to reset" &&
        git reset HEAD~1 &&
        git status >actual &&
index 28cbd19570a95815c5d2d40a4bb305e8be143d2a..c647a5eb58437f20e5fba8134d0cc964f706cdd9 100644 (file)
@@ -1504,6 +1504,9 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
        o->merge_size = len;
        mark_all_ce_unused(o->src_index);
 
+       if (o->src_index->fsmonitor_last_update)
+               o->result.fsmonitor_last_update = o->src_index->fsmonitor_last_update;
+
        /*
         * Sparse checkout loop #1: set NEW_SKIP_WORKTREE on existing entries
         */
@@ -2384,7 +2387,8 @@ int oneway_merge(const struct cache_entry * const *src,
 
        if (old && same(old, a)) {
                int update = 0;
-               if (o->reset && o->update && !ce_uptodate(old) && !ce_skip_worktree(old)) {
+               if (o->reset && o->update && !ce_uptodate(old) && !ce_skip_worktree(old) &&
+                       !(old->ce_flags & CE_FSMONITOR_VALID)) {
                        struct stat st;
                        if (lstat(old->name, &st) ||
                            ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE))