diff --git a/tests/test-fix.t b/tests/test-fix.t --- a/tests/test-fix.t +++ b/tests/test-fix.t @@ -1713,3 +1713,101 @@ r0.whole: hello + +We should execute the fixer tools as few times as possible, because they might +be slow or expensive to execute. The inputs to each execution are effectively +the file path, file content, and line ranges. So, we should be able to re-use +results whenever those inputs are repeated. That saves a lot of work when +fixing chains of commits that all have the same file revision for a path being +fixed. + + $ hg init numberofinvocations + $ cd numberofinvocations + + $ printf "bar1" > bar.log + $ printf "baz1" > baz.log + $ printf "foo1" > foo.log + $ printf "qux1" > qux.log + $ hg commit -Aqm "commit1" + + $ printf "bar2" > bar.log + $ printf "baz2" > baz.log + $ printf "foo2" > foo.log + $ hg commit -Aqm "commit2" + + $ printf "bar3" > bar.log + $ printf "baz3" > baz.log + $ hg commit -Aqm "commit3" + + $ printf "bar4" > bar.log + + $ LOGFILE=$TESTTMP/log + $ LOGGER=$TESTTMP/log.py + $ cat >> $LOGGER < # Appends the input file's name to the log file. + > import sys + > with open('$LOGFILE', 'a') as f: + > f.write(sys.argv[1] + '\n') + > sys.stdout.write(sys.stdin.read()) + > EOF + + $ hg fix --working-dir -r "all()" \ + > --config "fix.log:command=\"$PYTHON\" \"$LOGGER\" {rootpath}" \ + > --config "fix.log:pattern=glob:**.log" + + $ cat $LOGFILE | sort | uniq -c + 4 bar.log + 4 baz.log + 4 foo.log + 4 qux.log + + $ cd .. + +For tools that support line ranges, it's wrong to blindly re-use fixed file +content for the same file revision if it appears twice with different baserevs, +because the line ranges could be different. Since computing line ranges is +ambiguous, this isn't a matter of correctness, but it affects the usability of +this extension. It could maybe be simpler if baserevs were computed on a +per-file basis to make this situation impossible to construct. + +In the following example, we construct two subgraphs with the same file +revisions, and fix different sub-subgraphs to get different baserevs and +different changed line ranges. The key precondition is that revisions 1 and 4 +have the same file revision, and the key result is that their successors don't +have the same file content, because we want to fix different areas of that same +file revision's content. + + $ hg init differentlineranges + $ cd differentlineranges + + $ printf "a\nb\n" > file.changed + $ hg commit -Aqm "0 ab" + $ printf "a\nx\n" > file.changed + $ hg commit -Aqm "1 ax" + $ hg remove file.changed + $ hg commit -Aqm "2 removed" + $ hg revert file.changed -r 0 + $ hg commit -Aqm "3 ab (reverted)" + $ hg revert file.changed -r 1 + $ hg commit -Aqm "4 ax (reverted)" + + $ hg manifest --debug --template "{hash}\n" -r 0; \ + > hg manifest --debug --template "{hash}\n" -r 3 + 418f692145676128d2fb518b027ddbac624be76e + 418f692145676128d2fb518b027ddbac624be76e + $ hg manifest --debug --template "{hash}\n" -r 1; \ + > hg manifest --debug --template "{hash}\n" -r 4 + 09b8b3ce5a507caaa282f7262679e6d04091426c + 09b8b3ce5a507caaa282f7262679e6d04091426c + + $ hg fix --working-dir -r 1+3+4 + 3 new orphan changesets + + $ hg cat file.changed -r "successors(1)" --hidden + a + X + $ hg cat file.changed -r "successors(4)" --hidden + A + X + + $ cd ..