Skip to content

Commit f7937e0

Browse files
AaronMoatclaude
andcommitted
Validate .git/info/exclude files by hash as well as stat
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e44beb5 commit f7937e0

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

gix-dir/src/walk/untracked_cache.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,22 @@ pub(crate) fn validate<'a>(
106106
.iter()
107107
.filter_map(|list| list.source.as_deref())
108108
.find(|path| gix_path::realpath(*path).ok().as_deref() != Some(info_exclude_path.as_path()));
109+
let object_hash = index.object_hash();
109110
match (cache.excludes_file(), excludes_file) {
110111
(Some(expected), Some(path)) if validate_cached_stat(expected, path) => {}
111112
(None, None) => {}
112113
_ => return None,
113114
}
114-
// Also validate the cached .git/info/exclude stat+OID. If info/exclude changed since
115+
// Also validate the cached .git/info/exclude stat and OID. If info/exclude changed since
115116
// the UNTR snapshot was written, cached ignore decisions for directories could be stale.
117+
// We verify the content hash in addition to the stat to catch same-second, same-size edits.
116118
match cache.info_exclude() {
117-
Some(expected) if !validate_cached_stat(expected, &info_exclude_path) => return None,
119+
Some(expected)
120+
if !validate_cached_stat(expected, &info_exclude_path)
121+
|| !gitignore_matches(expected.id(), &info_exclude_path, object_hash) =>
122+
{
123+
return None
124+
}
118125
_ => {}
119126
}
120127

0 commit comments

Comments
 (0)