Skip to content

Commit f92dd57

Browse files
committed
status: keep preload overrides out of worktree proofs
2 parents dad9e3b + 4bc13b1 commit f92dd57

3 files changed

Lines changed: 185 additions & 2 deletions

File tree

clean-status-config.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ static int config_is_command_transport(const char *key,
7575
!strcmp(subkey, "pushinsteadof");
7676
}
7777

78+
static int config_is_command_acceleration(const char *key,
79+
const struct config_context *ctx)
80+
{
81+
return ctx && ctx->kvi && ctx->kvi->scope == CONFIG_SCOPE_COMMAND &&
82+
(!strcmp(key, "core.preloadindex") ||
83+
!strcmp(key, "core.preloadindexbulk"));
84+
}
85+
7886
static int config_is_tracked_policy(const char *key)
7987
{
8088
return !strcmp(key, "core.filemode") ||
@@ -101,8 +109,9 @@ void clean_status_config_add(struct clean_status_config_digest *digest,
101109

102110
if (!digest->initialized || digest->finalized)
103111
BUG("invalid clean-status config digest state");
104-
/* Process-local transport settings cannot change a worktree proof. */
105-
if (config_is_command_transport(key, ctx))
112+
/* Process-local transport and traversal settings cannot change a proof. */
113+
if (config_is_command_transport(key, ctx) ||
114+
config_is_command_acceleration(key, ctx))
106115
return;
107116
hash_config_entry(&digest->ctx, key, value, ctx);
108117
if (config_is_tracked_policy(key))

t/t7527-builtin-fsmonitor.sh

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6274,6 +6274,102 @@ test_expect_success UNTRACKED_CACHE,SEMANTIC_VERIFY_ANCHORED_OPEN \
62746274
)
62756275
'
62766276

6277+
test_expect_success UNTRACKED_CACHE,SEMANTIC_VERIFY_ANCHORED_OPEN \
6278+
'command-scoped preload tuning preserves configured filter history' '
6279+
test_when_finished "rm -rf configured-filter-preload" &&
6280+
test_create_repo configured-filter-preload &&
6281+
(
6282+
cd configured-filter-preload &&
6283+
sane_unset GIT_TEST_SPLIT_INDEX &&
6284+
mkdir nested &&
6285+
test_write_lines base >tracked &&
6286+
test_write_lines sibling >nested/tracked &&
6287+
test_write_lines "*.filtered filter=demo" \
6288+
"*.processed filter=protocol" >.gitattributes &&
6289+
git add .gitattributes tracked nested/tracked &&
6290+
git commit -m base &&
6291+
git config filter.demo.clean cat &&
6292+
git config filter.protocol.process \
6293+
"test-tool rot13-filter --log=.git/filter-process.log clean smudge" &&
6294+
git config core.untrackedCache true &&
6295+
git config core.fsmonitor true &&
6296+
GIT_TEST_FSMONITOR_QUERY_SEQUENCE=C \
6297+
git update-index --fsmonitor &&
6298+
GIT_INDEX_FILE="$PWD/.git/index" \
6299+
GIT_TEST_FSMONITOR_QUERY_SEQUENCE=CCCCCC \
6300+
GIT_TRACE2_EVENT="$PWD/.git/prime.trace" \
6301+
git status --porcelain=v2 >.git/prime &&
6302+
test_must_be_empty .git/prime &&
6303+
test_trace2_data fsmonitor filter-scope/valid 1 \
6304+
<.git/prime.trace &&
6305+
test_grep FSCF .git/index &&
6306+
test_grep FSUC .git/index &&
6307+
6308+
for label in bulk preload both bulk-false preload-false
6309+
do
6310+
case "$label" in
6311+
bulk) set -- -c core.preloadIndexBulk ;;
6312+
preload) set -- -c core.preloadIndex ;;
6313+
both) set -- -c core.preloadIndexBulk -c core.preloadIndex ;;
6314+
bulk-false) set -- -c core.preloadIndexBulk=false ;;
6315+
preload-false) set -- -c core.preloadIndex=false ;;
6316+
esac &&
6317+
GIT_TEST_FSMONITOR_QUERY_SEQUENCE=CCCCCC \
6318+
GIT_TRACE2_EVENT="$PWD/.git/$label.trace" \
6319+
git "$@" status --porcelain=v2 >.git/$label &&
6320+
test_must_be_empty .git/$label &&
6321+
test_trace2_data fsmonitor config/coherent 1 \
6322+
<.git/$label.trace &&
6323+
! test_trace2_data fsmonitor semantic/initial-mismatch 1 \
6324+
<.git/$label.trace &&
6325+
! have_t2_data_event fsmonitor semantic/manifest-scan-count \
6326+
<.git/$label.trace &&
6327+
! test_trace2_data fsmonitor semantic/strong-invalidation 1 \
6328+
<.git/$label.trace &&
6329+
! test_trace2_data index refresh/sum_lstat \
6330+
"[1-9][0-9]*" <.git/$label.trace &&
6331+
GIT_TEST_FSMONITOR_QUERY_SEQUENCE=CCCCCC \
6332+
GIT_TRACE2_EVENT="$PWD/.git/$label-plain.trace" \
6333+
git status --porcelain=v2 >.git/$label-plain &&
6334+
test_must_be_empty .git/$label-plain &&
6335+
test_trace2_data fsmonitor config/coherent 1 \
6336+
<.git/$label-plain.trace &&
6337+
! have_t2_data_event fsmonitor semantic/manifest-scan-count \
6338+
<.git/$label-plain.trace || return 1
6339+
done &&
6340+
6341+
git config core.preloadIndexBulk true &&
6342+
GIT_TEST_FSMONITOR_QUERY_SEQUENCE=CCCCCC \
6343+
GIT_TRACE2_EVENT="$PWD/.git/persistent.trace" \
6344+
git status --porcelain=v2 >.git/persistent &&
6345+
test_must_be_empty .git/persistent &&
6346+
test_trace2_data fsmonitor config/coherent 0 \
6347+
<.git/persistent.trace &&
6348+
test_trace2_data fsmonitor semantic/manifest-scan-count 1 \
6349+
<.git/persistent.trace &&
6350+
6351+
git config core.filemode false &&
6352+
chmod +x tracked &&
6353+
GIT_INDEX_FILE="$PWD/.git/index" \
6354+
GIT_TEST_FSMONITOR_QUERY_SEQUENCE=CCCCCC \
6355+
git status --porcelain=v2 >.git/filemode-prime &&
6356+
test_must_be_empty .git/filemode-prime &&
6357+
GIT_OPTIONAL_LOCKS=0 git -c core.fsmonitor=false \
6358+
-c core.untrackedCache=false -c core.filemode=true \
6359+
status --porcelain=v2 >.git/filemode.expect &&
6360+
test_grep "^1 \\.M .* tracked$" .git/filemode.expect &&
6361+
GIT_TEST_FSMONITOR_QUERY_SEQUENCE=CCCCCC \
6362+
GIT_TRACE2_EVENT="$PWD/.git/filemode.trace" \
6363+
git -c core.filemode=true status --porcelain=v2 \
6364+
>.git/filemode.actual &&
6365+
test_cmp .git/filemode.expect .git/filemode.actual &&
6366+
test_trace2_data fsmonitor config/coherent 0 \
6367+
<.git/filemode.trace &&
6368+
test_trace2_data fsmonitor semantic/manifest-scan-count 1 \
6369+
<.git/filemode.trace
6370+
)
6371+
'
6372+
62776373
test_expect_success SEMANTIC_VERIFY_ANCHORED_OPEN \
62786374
'sparse index rebuilds semantic history without expansion' '
62796375
test_when_finished "rm -rf sparse-semantic" &&

t/unit-tests/u-clean-status-config.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,84 @@ void test_clean_status_config__command_transport_config_does_not_change_proof(vo
109109
}
110110
}
111111

112+
void test_clean_status_config__command_preload_config_does_not_change_proof(void)
113+
{
114+
static const char *const ignored_keys[] = {
115+
"core.preloadindex",
116+
"core.preloadindexbulk",
117+
};
118+
static const enum config_scope persistent_scopes[] = {
119+
CONFIG_SCOPE_SYSTEM,
120+
CONFIG_SCOPE_GLOBAL,
121+
CONFIG_SCOPE_LOCAL,
122+
CONFIG_SCOPE_WORKTREE,
123+
CONFIG_SCOPE_UNKNOWN,
124+
};
125+
static const int algorithms[] = {
126+
GIT_HASH_SHA1,
127+
GIT_HASH_SHA256,
128+
};
129+
struct key_value_info kvi = KVI_INIT;
130+
struct config_context ctx = { .kvi = &kvi };
131+
132+
kvi.origin_type = CONFIG_ORIGIN_CMDLINE;
133+
for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) {
134+
const struct git_hash_algo *algo = &hash_algos[algorithms[i]];
135+
struct clean_status_config_digest baseline, digest;
136+
137+
clean_status_config_init(&baseline, algo);
138+
clean_status_config_final(&baseline);
139+
for (size_t j = 0; j < ARRAY_SIZE(ignored_keys); j++) {
140+
kvi.scope = CONFIG_SCOPE_COMMAND;
141+
clean_status_config_init(&digest, algo);
142+
clean_status_config_add(&digest, ignored_keys[j],
143+
"true", &ctx);
144+
clean_status_config_final(&digest);
145+
cl_assert(hasheq(digest.hash, baseline.hash, algo));
146+
cl_assert(hasheq(digest.semantic_hash,
147+
baseline.semantic_hash, algo));
148+
cl_assert(hasheq(digest.tracked_policy_hash,
149+
baseline.tracked_policy_hash, algo));
150+
151+
for (size_t scope = 0;
152+
scope < ARRAY_SIZE(persistent_scopes); scope++) {
153+
kvi.scope = persistent_scopes[scope];
154+
clean_status_config_init(&digest, algo);
155+
clean_status_config_add(&digest, ignored_keys[j],
156+
"true", &ctx);
157+
clean_status_config_final(&digest);
158+
cl_assert(!hasheq(digest.hash,
159+
baseline.hash, algo));
160+
cl_assert(hasheq(digest.semantic_hash,
161+
baseline.semantic_hash, algo));
162+
cl_assert(hasheq(digest.tracked_policy_hash,
163+
baseline.tracked_policy_hash, algo));
164+
}
165+
166+
clean_status_config_init(&digest, algo);
167+
clean_status_config_add(&digest, ignored_keys[j],
168+
"true", NULL);
169+
clean_status_config_final(&digest);
170+
cl_assert(!hasheq(digest.hash, baseline.hash, algo));
171+
}
172+
173+
kvi.scope = CONFIG_SCOPE_COMMAND;
174+
clean_status_config_init(&digest, algo);
175+
clean_status_config_add(&digest, "core.filemode", "true", &ctx);
176+
clean_status_config_final(&digest);
177+
cl_assert(!hasheq(digest.hash, baseline.hash, algo));
178+
cl_assert(!hasheq(digest.tracked_policy_hash,
179+
baseline.tracked_policy_hash, algo));
180+
181+
clean_status_config_init(&digest, algo);
182+
clean_status_config_add(&digest, "core.autocrlf", "true", &ctx);
183+
clean_status_config_final(&digest);
184+
cl_assert(!hasheq(digest.hash, baseline.hash, algo));
185+
cl_assert(!hasheq(digest.semantic_hash,
186+
baseline.semantic_hash, algo));
187+
}
188+
}
189+
112190
void test_clean_status_config__command_worktree_config_still_changes_proof(void)
113191
{
114192
static const char *const retained_keys[] = {

0 commit comments

Comments
 (0)