##// END OF EJS Templates
dirstate-v2: hash the source of the ignore patterns as well...
Raphaël Gomès -
r50453:363923bd stable
parent child Browse files
Show More
@@ -283,8 +283,16 b' We define:'
283 283 in inclusion order. This definition is recursive, as included files can
284 284 themselves include more files.
285 285
286 This hash is defined as the SHA-1 of the concatenation (in sorted
287 order) of the "expanded contents" of each "root" ignore file.
286 * "filepath" as the bytes of the ignore file path
287 relative to the root of the repository if inside the repository,
288 or the untouched path as defined in the configuration.
289
290 This hash is defined as the SHA-1 of the following line format:
291
292 <filepath> <sha1 of the "expanded contents">\n
293
294 for each "root" ignore file. (in sorted order)
295
288 296 (Note that computing this does not require actually concatenating
289 297 into a single contiguous byte sequence.
290 298 Instead a SHA-1 hasher object can be created
@@ -10,6 +10,7 b' use crate::dirstate_tree::on_disk::Dirst'
10 10 use crate::matchers::get_ignore_function;
11 11 use crate::matchers::Matcher;
12 12 use crate::utils::files::get_bytes_from_os_string;
13 use crate::utils::files::get_bytes_from_path;
13 14 use crate::utils::files::get_path_from_bytes;
14 15 use crate::utils::hg_path::HgPath;
15 16 use crate::BadMatch;
@@ -66,7 +67,7 b" pub fn status<'dirstate>("
66 67 let (ignore_fn, warnings) = get_ignore_function(
67 68 ignore_files,
68 69 &root_dir,
69 &mut |_pattern_bytes| {},
70 &mut |_source, _pattern_bytes| {},
70 71 )?;
71 72 (ignore_fn, warnings, None)
72 73 }
@@ -75,7 +76,24 b" pub fn status<'dirstate>("
75 76 let (ignore_fn, warnings) = get_ignore_function(
76 77 ignore_files,
77 78 &root_dir,
78 &mut |pattern_bytes| hasher.update(pattern_bytes),
79 &mut |source, pattern_bytes| {
80 // If inside the repo, use the relative version to
81 // make it deterministic inside tests.
82 // The performance hit should be negligible.
83 let source = source
84 .strip_prefix(&root_dir)
85 .unwrap_or(source);
86 let source = get_bytes_from_path(source);
87
88 let mut subhasher = Sha1::new();
89 subhasher.update(pattern_bytes);
90 let patterns_hash = subhasher.finalize();
91
92 hasher.update(source);
93 hasher.update(b" ");
94 hasher.update(patterns_hash);
95 hasher.update(b"\n");
96 },
79 97 )?;
80 98 let new_hash = *hasher.finalize().as_ref();
81 99 let changed = new_hash != dmap.ignore_patterns_hash;
@@ -412,11 +412,11 b' pub fn parse_pattern_file_contents('
412 412 pub fn read_pattern_file(
413 413 file_path: &Path,
414 414 warn: bool,
415 inspect_pattern_bytes: &mut impl FnMut(&[u8]),
415 inspect_pattern_bytes: &mut impl FnMut(&Path, &[u8]),
416 416 ) -> Result<(Vec<IgnorePattern>, Vec<PatternFileWarning>), PatternError> {
417 417 match std::fs::read(file_path) {
418 418 Ok(contents) => {
419 inspect_pattern_bytes(&contents);
419 inspect_pattern_bytes(file_path, &contents);
420 420 parse_pattern_file_contents(&contents, file_path, None, warn)
421 421 }
422 422 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok((
@@ -455,7 +455,7 b' pub type PatternResult<T> = Result<T, Pa'
455 455 pub fn get_patterns_from_file(
456 456 pattern_file: &Path,
457 457 root_dir: &Path,
458 inspect_pattern_bytes: &mut impl FnMut(&[u8]),
458 inspect_pattern_bytes: &mut impl FnMut(&Path, &[u8]),
459 459 ) -> PatternResult<(Vec<IgnorePattern>, Vec<PatternFileWarning>)> {
460 460 let (patterns, mut warnings) =
461 461 read_pattern_file(pattern_file, true, inspect_pattern_bytes)?;
@@ -838,7 +838,7 b" fn build_match<'a, 'b>("
838 838 pub fn get_ignore_matcher<'a>(
839 839 mut all_pattern_files: Vec<PathBuf>,
840 840 root_dir: &Path,
841 inspect_pattern_bytes: &mut impl FnMut(&[u8]),
841 inspect_pattern_bytes: &mut impl FnMut(&Path, &[u8]),
842 842 ) -> PatternResult<(IncludeMatcher<'a>, Vec<PatternFileWarning>)> {
843 843 let mut all_patterns = vec![];
844 844 let mut all_warnings = vec![];
@@ -871,7 +871,7 b" pub fn get_ignore_matcher<'a>("
871 871 pub fn get_ignore_function<'a>(
872 872 all_pattern_files: Vec<PathBuf>,
873 873 root_dir: &Path,
874 inspect_pattern_bytes: &mut impl FnMut(&[u8]),
874 inspect_pattern_bytes: &mut impl FnMut(&Path, &[u8]),
875 875 ) -> PatternResult<(IgnoreFnType<'a>, Vec<PatternFileWarning>)> {
876 876 let res =
877 877 get_ignore_matcher(all_pattern_files, root_dir, inspect_pattern_bytes);
@@ -25,7 +25,7 b' pub fn run(invocation: &crate::CliInvoca'
25 25 let (ignore_matcher, warnings) = get_ignore_matcher(
26 26 vec![ignore_file],
27 27 &repo.working_directory_path().to_owned(),
28 &mut |_pattern_bytes| (),
28 &mut |_source, _pattern_bytes| (),
29 29 )
30 30 .map_err(|e| StatusError::from(e))?;
31 31
@@ -421,18 +421,24 b' Windows paths are accepted on input'
421 421 Check the hash of ignore patterns written in the dirstate
422 422 This is an optimization that is only relevant when using the Rust extensions
423 423
424 $ cat_filename_and_hash () {
425 > for i in "$@"; do
426 > printf "$i "
427 > cat "$i" | "$TESTDIR"/f --raw-sha1 | sed 's/^raw-sha1=//'
428 > done
429 > }
424 430 $ hg status > /dev/null
425 $ cat .hg/testhgignore .hg/testhgignorerel .hgignore dir2/.hgignore dir1/.hgignore dir1/.hgignoretwo | $TESTDIR/f --sha1
426 sha1=6e315b60f15fb5dfa02be00f3e2c8f923051f5ff
431 $ cat_filename_and_hash .hg/testhgignore .hg/testhgignorerel .hgignore dir2/.hgignore dir1/.hgignore dir1/.hgignoretwo | $TESTDIR/f --sha1
432 sha1=c0beb296395d48ced8e14f39009c4ea6e409bfe6
427 433 $ hg debugstate --docket | grep ignore
428 ignore pattern hash: 6e315b60f15fb5dfa02be00f3e2c8f923051f5ff
434 ignore pattern hash: c0beb296395d48ced8e14f39009c4ea6e409bfe6
429 435
430 436 $ echo rel > .hg/testhgignorerel
431 437 $ hg status > /dev/null
432 $ cat .hg/testhgignore .hg/testhgignorerel .hgignore dir2/.hgignore dir1/.hgignore dir1/.hgignoretwo | $TESTDIR/f --sha1
433 sha1=dea19cc7119213f24b6b582a4bae7b0cb063e34e
438 $ cat_filename_and_hash .hg/testhgignore .hg/testhgignorerel .hgignore dir2/.hgignore dir1/.hgignore dir1/.hgignoretwo | $TESTDIR/f --sha1
439 sha1=b8e63d3428ec38abc68baa27631516d5ec46b7fa
434 440 $ hg debugstate --docket | grep ignore
435 ignore pattern hash: dea19cc7119213f24b6b582a4bae7b0cb063e34e
441 ignore pattern hash: b8e63d3428ec38abc68baa27631516d5ec46b7fa
436 442 $ cd ..
437 443
438 444 Check that the hash depends on the source of the hgignore patterns
@@ -460,6 +466,6 b' Check that the hash depends on the sourc'
460 466 $ hg status
461 467 M dir1/.hgignore
462 468 M dir2/.hgignore
463 ? dir1/subdir/ignored1 (missing-correct-output !)
469 ? dir1/subdir/ignored1
464 470
465 471 #endif
General Comments 0
You need to be logged in to leave comments. Login now