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| |
|
|
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 |
|
|
469 | ? dir1/subdir/ignored1 | |
|
464 | 470 | |
|
465 | 471 | #endif |
General Comments 0
You need to be logged in to leave comments.
Login now