summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerrick Stolee <dstolee@microsoft.com>2021-07-14 13:12:39 (GMT)
committerJunio C Hamano <gitster@pobox.com>2021-07-14 20:42:49 (GMT)
commitf8fe49e53958f19b0e62e9549a80fcaa56d2f3cf (patch)
tree79898035fb5a4f14216204fd0e984754a23bacea
parentfe0d576153117953189e03d6c2c09445ccad4977 (diff)
downloadgit-f8fe49e53958f19b0e62e9549a80fcaa56d2f3cf.zip
git-f8fe49e53958f19b0e62e9549a80fcaa56d2f3cf.tar.gz
git-f8fe49e53958f19b0e62e9549a80fcaa56d2f3cf.tar.bz2
fsmonitor: integrate with sparse index
If we need to expand a sparse-index into a full one, then the FS Monitor bitmap is going to be incorrect. Ensure that we start fresh at such an event. While this is currently a performance drawback, the eventual hope of the sparse-index feature is that these expansions will be rare and hence we will be able to keep the FS Monitor data accurate across multiple Git commands. These tests are added to demonstrate that the behavior is the same across a full index and a sparse index, but also that file modifications to a tracked directory outside of the sparse cone will trigger ensure_full_index(). Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--sparse-index.c7
-rwxr-xr-xt/t7519-status-fsmonitor.sh49
2 files changed, 56 insertions, 0 deletions
diff --git a/sparse-index.c b/sparse-index.c
index ef53bd2..53c8f71 100644
--- a/sparse-index.c
+++ b/sparse-index.c
@@ -186,6 +186,10 @@ int convert_to_sparse(struct index_state *istate)
cache_tree_free(&istate->cache_tree);
cache_tree_update(istate, 0);
+ istate->fsmonitor_has_run_once = 0;
+ FREE_AND_NULL(istate->fsmonitor_dirty);
+ FREE_AND_NULL(istate->fsmonitor_last_update);
+
istate->sparse_index = 1;
trace2_region_leave("index", "convert_to_sparse", istate->repo);
return 0;
@@ -282,6 +286,9 @@ void ensure_full_index(struct index_state *istate)
istate->cache = full->cache;
istate->cache_nr = full->cache_nr;
istate->cache_alloc = full->cache_alloc;
+ istate->fsmonitor_has_run_once = 0;
+ FREE_AND_NULL(istate->fsmonitor_dirty);
+ FREE_AND_NULL(istate->fsmonitor_last_update);
strbuf_release(&base);
free(full);
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 637391c..deea88d 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -73,6 +73,7 @@ test_expect_success 'setup' '
expect*
actual*
marker*
+ trace2*
EOF
'
@@ -383,4 +384,52 @@ test_expect_success 'status succeeds after staging/unstaging' '
)
'
+# Usage:
+# check_sparse_index_behavior [!]
+# If "!" is supplied, then we verify that we do not call ensure_full_index
+# during a call to 'git status'. Otherwise, we verify that we _do_ call it.
+check_sparse_index_behavior () {
+ git status --porcelain=v2 >expect &&
+ git sparse-checkout init --cone --sparse-index &&
+ git sparse-checkout set dir1 dir2 &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
+ git status --porcelain=v2 >actual &&
+ test_region $1 index ensure_full_index trace2.txt &&
+ test_region fsm_hook query trace2.txt &&
+ test_cmp expect actual &&
+ rm trace2.txt &&
+ git sparse-checkout disable
+}
+
+test_expect_success 'status succeeds with sparse index' '
+ git reset --hard &&
+
+ test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" &&
+ check_sparse_index_behavior ! &&
+
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
+ EOF
+ git config core.fsmonitor .git/hooks/fsmonitor-test &&
+ check_sparse_index_behavior ! &&
+
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
+ printf "dir1/modified\0"
+ EOF
+ check_sparse_index_behavior ! &&
+
+ cp -r dir1 dir1a &&
+ git add dir1a &&
+ git commit -m "add dir1a" &&
+
+ # This one modifies outside the sparse-checkout definition
+ # and hence we expect to expand the sparse-index.
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
+ printf "dir1a/modified\0"
+ EOF
+ check_sparse_index_behavior
+'
+
test_done