test-fix-topology.t
521 lines
| 10.9 KiB
| text/troff
|
Tads3Lexer
/ tests / test-fix-topology.t
Danny Hooper
|
r37578 | A script that implements uppercasing all letters in a file. | ||
$ UPPERCASEPY="$TESTTMP/uppercase.py" | ||||
$ cat > $UPPERCASEPY <<EOF | ||||
> import sys | ||||
> from mercurial.utils.procutil import setbinary | ||||
> setbinary(sys.stdin) | ||||
> setbinary(sys.stdout) | ||||
> sys.stdout.write(sys.stdin.read().upper()) | ||||
> EOF | ||||
$ TESTLINES="foo\nbar\nbaz\n" | ||||
Matt Harbison
|
r39743 | $ printf $TESTLINES | "$PYTHON" $UPPERCASEPY | ||
Danny Hooper
|
r37578 | FOO | ||
BAR | ||||
BAZ | ||||
Danny Hooper
|
r37200 | Tests for the fix extension's behavior around non-trivial history topologies. | ||
Looks for correct incremental fixing and reproduction of parent/child | ||||
relationships. We indicate fixed file content by uppercasing it. | ||||
$ cat >> $HGRCPATH <<EOF | ||||
> [extensions] | ||||
> fix = | ||||
Martin von Zweigbergk
|
r45064 | > strip = | ||
Danny Hooper
|
r37200 | > [fix] | ||
Matt Harbison
|
r39743 | > uppercase-whole-file:command="$PYTHON" $UPPERCASEPY | ||
Danny Hooper
|
r40569 | > uppercase-whole-file:pattern=set:** | ||
Danny Hooper
|
r37200 | > EOF | ||
This tests the only behavior that should really be affected by obsolescence, so | ||||
we'll test it with evolution off and on. This only changes the revision | ||||
numbers, if all is well. | ||||
#testcases obsstore-off obsstore-on | ||||
#if obsstore-on | ||||
$ cat >> $HGRCPATH <<EOF | ||||
> [experimental] | ||||
> evolution.createmarkers=True | ||||
> evolution.allowunstable=True | ||||
> EOF | ||||
#endif | ||||
Setting up the test topology. Scroll down to see the graph produced. We make it | ||||
clear which files were modified in each revision. It's enough to test at the | ||||
file granularity, because that demonstrates which baserevs were diffed against. | ||||
The computation of changed lines is orthogonal and tested separately. | ||||
$ hg init repo | ||||
$ cd repo | ||||
$ printf "aaaa\n" > a | ||||
$ hg commit -Am "change A" | ||||
adding a | ||||
$ printf "bbbb\n" > b | ||||
$ hg commit -Am "change B" | ||||
adding b | ||||
$ printf "cccc\n" > c | ||||
$ hg commit -Am "change C" | ||||
adding c | ||||
$ hg checkout 0 | ||||
0 files updated, 0 files merged, 2 files removed, 0 files unresolved | ||||
$ printf "dddd\n" > d | ||||
$ hg commit -Am "change D" | ||||
adding d | ||||
created new head | ||||
$ hg merge -r 2 | ||||
2 files updated, 0 files merged, 0 files removed, 0 files unresolved | ||||
(branch merge, don't forget to commit) | ||||
$ printf "eeee\n" > e | ||||
$ hg commit -Am "change E" | ||||
adding e | ||||
$ hg checkout 0 | ||||
0 files updated, 0 files merged, 4 files removed, 0 files unresolved | ||||
$ printf "ffff\n" > f | ||||
$ hg commit -Am "change F" | ||||
adding f | ||||
created new head | ||||
$ hg checkout 0 | ||||
0 files updated, 0 files merged, 1 files removed, 0 files unresolved | ||||
$ printf "gggg\n" > g | ||||
$ hg commit -Am "change G" | ||||
adding g | ||||
created new head | ||||
$ hg merge -r 5 | ||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved | ||||
(branch merge, don't forget to commit) | ||||
$ printf "hhhh\n" > h | ||||
$ hg commit -Am "change H" | ||||
adding h | ||||
$ hg merge -r 4 | ||||
4 files updated, 0 files merged, 0 files removed, 0 files unresolved | ||||
(branch merge, don't forget to commit) | ||||
$ printf "iiii\n" > i | ||||
$ hg commit -Am "change I" | ||||
adding i | ||||
$ hg checkout 2 | ||||
0 files updated, 0 files merged, 6 files removed, 0 files unresolved | ||||
$ printf "jjjj\n" > j | ||||
$ hg commit -Am "change J" | ||||
adding j | ||||
created new head | ||||
$ hg checkout 7 | ||||
3 files updated, 0 files merged, 3 files removed, 0 files unresolved | ||||
$ printf "kkkk\n" > k | ||||
$ hg add | ||||
adding k | ||||
$ hg log --graph --template '{rev} {desc}\n' | ||||
o 9 change J | ||||
| | ||||
| o 8 change I | ||||
| |\ | ||||
| | @ 7 change H | ||||
| | |\ | ||||
| | | o 6 change G | ||||
| | | | | ||||
| | o | 5 change F | ||||
| | |/ | ||||
| o | 4 change E | ||||
|/| | | ||||
| o | 3 change D | ||||
| |/ | ||||
o | 2 change C | ||||
| | | ||||
o | 1 change B | ||||
|/ | ||||
o 0 change A | ||||
Fix all but the root revision and its four children. | ||||
$ hg fix -r '2|4|7|8|9' --working-dir | ||||
Martin von Zweigbergk
|
r45047 | saved backup bundle to * (glob) (obsstore-off !) | ||
Danny Hooper
|
r37200 | |||
The five revisions remain, but the other revisions were fixed and replaced. All | ||||
parent pointers have been accurately set to reproduce the previous topology | ||||
(though it is rendered in a slightly different order now). | ||||
#if obsstore-on | ||||
$ hg log --graph --template '{rev} {desc}\n' | ||||
o 14 change J | ||||
| | ||||
| o 13 change I | ||||
| |\ | ||||
| | @ 12 change H | ||||
| | |\ | ||||
| o | | 11 change E | ||||
|/| | | | ||||
o | | | 10 change C | ||||
| | | | | ||||
| | | o 6 change G | ||||
| | | | | ||||
| | o | 5 change F | ||||
| | |/ | ||||
| o / 3 change D | ||||
| |/ | ||||
o / 1 change B | ||||
|/ | ||||
o 0 change A | ||||
$ C=10 | ||||
$ E=11 | ||||
$ H=12 | ||||
$ I=13 | ||||
$ J=14 | ||||
#else | ||||
$ hg log --graph --template '{rev} {desc}\n' | ||||
o 9 change J | ||||
| | ||||
| o 8 change I | ||||
| |\ | ||||
| | @ 7 change H | ||||
| | |\ | ||||
| o | | 6 change E | ||||
|/| | | | ||||
o | | | 5 change C | ||||
| | | | | ||||
| | | o 4 change G | ||||
| | | | | ||||
| | o | 3 change F | ||||
| | |/ | ||||
| o / 2 change D | ||||
| |/ | ||||
o / 1 change B | ||||
|/ | ||||
o 0 change A | ||||
$ C=5 | ||||
$ E=6 | ||||
$ H=7 | ||||
$ I=8 | ||||
$ J=9 | ||||
#endif | ||||
Change C is a root of the set being fixed, so all we fix is what has changed | ||||
since its parent. That parent, change B, is its baserev. | ||||
$ hg cat -r $C 'set:**' | ||||
aaaa | ||||
bbbb | ||||
CCCC | ||||
Change E is a merge with only one parent being fixed. Its baserevs are the | ||||
unfixed parent plus the baserevs of the other parent. This evaluates to changes | ||||
B and D. We now have to decide what it means to incrementally fix a merge | ||||
commit. We choose to fix anything that has changed versus any baserev. Only the | ||||
undisturbed content of the common ancestor, change A, is unfixed. | ||||
$ hg cat -r $E 'set:**' | ||||
aaaa | ||||
BBBB | ||||
CCCC | ||||
DDDD | ||||
EEEE | ||||
Change H is a merge with neither parent being fixed. This is essentially | ||||
equivalent to the previous case because there is still only one baserev for | ||||
each parent of the merge. | ||||
$ hg cat -r $H 'set:**' | ||||
aaaa | ||||
FFFF | ||||
GGGG | ||||
HHHH | ||||
Change I is a merge that has four baserevs; two from each parent. We handle | ||||
multiple baserevs in the same way regardless of how many came from each parent. | ||||
So, fixing change H will fix any files that were not exactly the same in each | ||||
baserev. | ||||
$ hg cat -r $I 'set:**' | ||||
aaaa | ||||
BBBB | ||||
CCCC | ||||
DDDD | ||||
EEEE | ||||
FFFF | ||||
GGGG | ||||
HHHH | ||||
IIII | ||||
Change J is a simple case with one baserev, but its baserev is not its parent, | ||||
change C. Its baserev is its grandparent, change B. | ||||
$ hg cat -r $J 'set:**' | ||||
aaaa | ||||
bbbb | ||||
CCCC | ||||
JJJJ | ||||
The working copy was dirty, so it is treated much like a revision. The baserevs | ||||
for the working copy are inherited from its parent, change H, because it is | ||||
also being fixed. | ||||
$ cat * | ||||
aaaa | ||||
FFFF | ||||
GGGG | ||||
HHHH | ||||
KKKK | ||||
Change A was never a baserev because none of its children were to be fixed. | ||||
$ cd .. | ||||
Martin von Zweigbergk
|
r45064 | |||
Test the --source option. We only do this with obsstore on to avoid duplicating | ||||
test code. We rely on the other tests to prove that obsolescence is not an | ||||
important factor here. | ||||
#if obsstore-on | ||||
$ hg init source-arg | ||||
$ cd source-arg | ||||
$ printf "aaaa\n" > a | ||||
$ hg commit -Am "change A" | ||||
adding a | ||||
$ printf "bbbb\n" > b | ||||
$ hg commit -Am "change B" | ||||
adding b | ||||
$ printf "cccc\n" > c | ||||
$ hg commit -Am "change C" | ||||
adding c | ||||
$ hg checkout 0 | ||||
0 files updated, 0 files merged, 2 files removed, 0 files unresolved | ||||
$ printf "dddd\n" > d | ||||
$ hg commit -Am "change D" | ||||
adding d | ||||
created new head | ||||
$ hg log --graph --template '{rev} {desc}\n' | ||||
@ 3 change D | ||||
| | ||||
| o 2 change C | ||||
| | | ||||
| o 1 change B | ||||
|/ | ||||
o 0 change A | ||||
Test passing 'wdir()' to --source | ||||
$ printf "xxxx\n" > x | ||||
$ hg add x | ||||
$ hg fix -s 'wdir()' | ||||
$ cat * | ||||
aaaa | ||||
dddd | ||||
XXXX | ||||
Test passing '.' to --source | ||||
$ printf "xxxx\n" > x | ||||
$ hg fix -s . | ||||
$ hg log --graph --template '{rev} {desc}\n' | ||||
@ 4 change D | ||||
| | ||||
| o 2 change C | ||||
| | | ||||
| o 1 change B | ||||
|/ | ||||
o 0 change A | ||||
$ cat * | ||||
aaaa | ||||
DDDD | ||||
XXXX | ||||
$ hg strip -qf 4 | ||||
$ hg co -q 3 | ||||
Test passing other branch to --source | ||||
$ printf "xxxx\n" > x | ||||
$ hg add x | ||||
$ hg fix -s 2 | ||||
$ hg log --graph --template '{rev} {desc}\n' | ||||
o 4 change C | ||||
| | ||||
| @ 3 change D | ||||
| | | ||||
o | 1 change B | ||||
|/ | ||||
o 0 change A | ||||
$ hg cat -r 4 b c | ||||
bbbb | ||||
CCCC | ||||
$ cat * | ||||
aaaa | ||||
dddd | ||||
xxxx | ||||
$ hg strip -qf 4 | ||||
Test passing multiple revisions to --source | ||||
$ hg fix -s '2 + .' | ||||
$ hg log --graph --template '{rev} {desc}\n' | ||||
@ 5 change D | ||||
| | ||||
| o 4 change C | ||||
| | | ||||
| o 1 change B | ||||
|/ | ||||
o 0 change A | ||||
$ hg cat -r 4 b c | ||||
bbbb | ||||
CCCC | ||||
$ cat * | ||||
aaaa | ||||
DDDD | ||||
XXXX | ||||
$ cd .. | ||||
#endif | ||||
Danny Hooper
|
r37613 | The --all flag should fix anything that wouldn't cause a problem if you fixed | ||
it, including the working copy. Obsolete revisions are not fixed because that | ||||
could cause divergence. Public revisions would cause an abort because they are | ||||
immutable. We can fix orphans because their successors are still just orphans | ||||
of the original obsolete parent. When obsolesence is off, we're just fixing and | ||||
replacing anything that isn't public. | ||||
$ hg init fixall | ||||
$ cd fixall | ||||
Martin von Zweigbergk
|
r45048 | $ hg fix --all --working-dir | ||
abort: cannot specify both --working-dir and --all | ||||
[255] | ||||
Danny Hooper
|
r37613 | |||
#if obsstore-on | ||||
$ printf "one\n" > foo.whole | ||||
$ hg commit -Aqm "first" | ||||
$ hg phase --public | ||||
$ hg tag --local root | ||||
$ printf "two\n" > foo.whole | ||||
$ hg commit -m "second" | ||||
$ printf "three\n" > foo.whole | ||||
$ hg commit -m "third" --secret | ||||
$ hg tag --local secret | ||||
$ hg checkout root | ||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved | ||||
$ printf "four\n" > foo.whole | ||||
$ hg commit -m "fourth" | ||||
created new head | ||||
$ printf "five\n" > foo.whole | ||||
$ hg commit -m "fifth" | ||||
$ hg tag --local replaced | ||||
$ printf "six\n" > foo.whole | ||||
$ hg commit -m "sixth" | ||||
$ hg checkout replaced | ||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved | ||||
$ printf "seven\n" > foo.whole | ||||
$ hg commit --amend | ||||
1 new orphan changesets | ||||
$ hg checkout secret | ||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved | ||||
$ printf "uncommitted\n" > foo.whole | ||||
$ hg log --graph --template '{rev} {desc} {phase}\n' | ||||
o 6 fifth draft | ||||
| | ||||
| * 5 sixth draft | ||||
| | | ||||
| x 4 fifth draft | ||||
|/ | ||||
o 3 fourth draft | ||||
| | ||||
| @ 2 third secret | ||||
| | | ||||
| o 1 second draft | ||||
|/ | ||||
o 0 first public | ||||
$ hg fix --all | ||||
$ hg log --graph --template '{rev} {desc}\n' -r 'sort(all(), topo)' --hidden | ||||
o 11 fifth | ||||
| | ||||
o 9 fourth | ||||
| | ||||
| @ 8 third | ||||
| | | ||||
| o 7 second | ||||
|/ | ||||
| * 10 sixth | ||||
| | | ||||
| | x 5 sixth | ||||
| |/ | ||||
| x 4 fifth | ||||
| | | ||||
| | x 6 fifth | ||||
| |/ | ||||
| x 3 fourth | ||||
|/ | ||||
| x 2 third | ||||
| | | ||||
| x 1 second | ||||
|/ | ||||
o 0 first | ||||
$ hg cat -r 7 foo.whole | ||||
TWO | ||||
$ hg cat -r 8 foo.whole | ||||
THREE | ||||
$ hg cat -r 9 foo.whole | ||||
FOUR | ||||
$ hg cat -r 10 foo.whole | ||||
SIX | ||||
$ hg cat -r 11 foo.whole | ||||
SEVEN | ||||
$ cat foo.whole | ||||
UNCOMMITTED | ||||
#else | ||||
$ printf "one\n" > foo.whole | ||||
$ hg commit -Aqm "first" | ||||
$ hg phase --public | ||||
$ hg tag --local root | ||||
$ printf "two\n" > foo.whole | ||||
$ hg commit -m "second" | ||||
$ printf "three\n" > foo.whole | ||||
$ hg commit -m "third" --secret | ||||
$ hg tag --local secret | ||||
$ hg checkout root | ||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved | ||||
$ printf "four\n" > foo.whole | ||||
$ hg commit -m "fourth" | ||||
created new head | ||||
$ printf "uncommitted\n" > foo.whole | ||||
$ hg log --graph --template '{rev} {desc} {phase}\n' | ||||
@ 3 fourth draft | ||||
| | ||||
| o 2 third secret | ||||
| | | ||||
| o 1 second draft | ||||
|/ | ||||
o 0 first public | ||||
$ hg fix --all | ||||
saved backup bundle to * (glob) | ||||
$ hg log --graph --template '{rev} {desc} {phase}\n' | ||||
@ 3 fourth draft | ||||
| | ||||
| o 2 third secret | ||||
| | | ||||
| o 1 second draft | ||||
|/ | ||||
o 0 first public | ||||
$ hg cat -r 0 foo.whole | ||||
one | ||||
$ hg cat -r 1 foo.whole | ||||
TWO | ||||
$ hg cat -r 2 foo.whole | ||||
THREE | ||||
$ hg cat -r 3 foo.whole | ||||
FOUR | ||||
$ cat foo.whole | ||||
UNCOMMITTED | ||||
#endif | ||||
$ cd .. | ||||