merge: do early copy to deal with issue636
Without copies/renames, merges source names are 1:1 with their
targets. Copies and renames introduce the possibility that there will
be two merges with the same input but different output. By doing the
copy to the destination name before the merge, the actual merge
becomes 1:1 again, and no source is the input to two different merges.
- add a preliminary scan to applyupdates to do copies
- for the merge action, pass the old name (for finding ancestors) and
the new name (for input to the merge) to filemerge
- eliminate the old post-merge copy
- lookup file contents from new name in filemerge
- pass new name to external merge helper
- report merge failure at new name
- add a test
#!/bin/sh
mkdir t
cd t
hg init
hg id
echo a > a
hg add a
hg commit -m "test" -d "1000000 0"
hg co
hg identify
T=`hg tip --debug | head -n 1 | cut -d : -f 3`
hg tag -l "This is a local tag with a really long name!"
hg tags
rm .hg/localtags
echo "$T first" > .hgtags
cat .hgtags
hg add .hgtags
hg commit -m "add tags" -d "1000000 0"
hg tags
hg identify
echo bb > a
hg status
hg identify
hg co first
hg id
hg -v id
hg status
echo 1 > b
hg add b
hg commit -m "branch" -d "1000000 0"
hg id
hg merge 1
hg id
hg status
hg commit -m "merge" -d "1000000 0"
# create fake head, make sure tag not visible afterwards
cp .hgtags tags
hg tag -d "1000000 0" last
hg rm .hgtags
hg commit -m "remove" -d "1000000 0"
mv tags .hgtags
hg add .hgtags
hg commit -m "readd" -d "1000000 0"
hg tags
# invalid tags
echo "spam" >> .hgtags
echo >> .hgtags
echo "foo bar" >> .hgtags
echo "$T invalid" | sed "s/..../a5a5/" >> .hg/localtags
hg commit -m "tags" -d "1000000 0"
# report tag parse error on other head
hg up 3
echo 'x y' >> .hgtags
hg commit -m "head" -d "1000000 0"
hg tags
hg tip
# test tag precedence rules
cd ..
hg init t2
cd t2
echo foo > foo
hg add foo
hg ci -m 'add foo' -d '1000000 0' # rev 0
hg tag -d '1000000 0' bar # rev 1
echo >> foo
hg ci -m 'change foo 1' -d '1000000 0' # rev 2
hg up -C 1
hg tag -r 1 -d '1000000 0' -f bar # rev 3
hg up -C 1
echo >> foo
hg ci -m 'change foo 2' -d '1000000 0' # rev 4
hg tags
# test tag removal
hg tag --remove -d '1000000 0' bar
hg tip
hg tags
echo '% remove nonexistent tag'
hg tag --remove -d '1000000 0' foobar
hg tip
# test tag rank
cd ..
hg init t3
cd t3
echo foo > foo
hg add foo
hg ci -m 'add foo' -d '1000000 0' # rev 0
hg tag -d '1000000 0' -f bar # rev 1 bar -> 0
hg tag -d '1000000 0' -f bar # rev 2 bar -> 1
hg tag -d '1000000 0' -fr 0 bar # rev 3 bar -> 0
hg tag -d '1000000 0' -fr 1 bar # rev 3 bar -> 1
hg tag -d '1000000 0' -fr 0 bar # rev 4 bar -> 0
hg tags
hg co 3
echo barbar > foo
hg ci -m 'change foo' -d '1000000 0' # rev 0
hg tags
hg tag -d '1000000 0' -r 3 bar # should complain
hg tags
# test tag rank with 3 heads
cd ..
hg init t4
cd t4
echo foo > foo
hg add
hg ci -m 'add foo' -d '0 0' # rev 0
hg tag -d '0 0' bar # rev 1 bar -> 0
hg tag -d '0 0' -f bar # rev 2 bar -> 1
hg up -qC 0
hg tag -d '0 0' -fr 2 bar # rev 3 bar -> 2
hg tags
hg up -qC 0
hg tag -d '0 0' -m 'retag rev 0' -fr 0 bar # rev 4 bar -> 0, but bar stays at 2
echo % bar should still point to rev 2
hg tags