Mercurial > hg
view tests/test-merge-tools.t @ 29218:fd288d118074
largefiles: send statlfile remote calls only for nonexisting locally files
Files that are already in local store should be checked locally. The problem
with this implementation is how difference in messages between local and remote
checks should look like. For now local errors for file missing and content
corrupted looks like this:
'changeset cset: filename references missing storepath\n'
'changeset cset: filename references corrupted storepath\n'
for remote it looks like:
'changeset cset: filename missing\n'
'changeset cset: filename: contents differ\n'
Contents differ error for remote calls is never raised currently - for now
statlfile implementation lacks checking file content.
author | liscju <piotr.listkiewicz@gmail.com> |
---|---|
date | Mon, 09 May 2016 10:05:32 +0200 |
parents | 88d5db4b155c |
children | 940c05b25b07 |
line wrap: on
line source
test merge-tools configuration - mostly exercising filemerge.py $ unset HGMERGE # make sure HGMERGE doesn't interfere with the test $ hg init revision 0 $ echo "revision 0" > f $ echo "space" >> f $ hg commit -Am "revision 0" adding f revision 1 $ echo "revision 1" > f $ echo "space" >> f $ hg commit -Am "revision 1" $ hg update 0 > /dev/null revision 2 $ echo "revision 2" > f $ echo "space" >> f $ hg commit -Am "revision 2" created new head $ hg update 0 > /dev/null revision 3 - simple to merge $ echo "revision 3" >> f $ hg commit -Am "revision 3" created new head revision 4 - hard to merge $ hg update 0 > /dev/null $ echo "revision 4" > f $ hg commit -Am "revision 4" created new head $ echo "[merge-tools]" > .hg/hgrc $ beforemerge() { > cat .hg/hgrc > echo "# hg update -C 1" > hg update -C 1 > /dev/null > } $ aftermerge() { > echo "# cat f" > cat f > echo "# hg stat" > hg stat > echo "# hg resolve --list" > hg resolve --list > rm -f f.orig > } Tool selection default is internal merge: $ beforemerge [merge-tools] # hg update -C 1 hg merge -r 2 override $PATH to ensure hgmerge not visible; use $PYTHON in case we're running from a devel copy, not a temp installation $ PATH="$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2 merging f warning: conflicts while merging f! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f <<<<<<< local: ef83787e2614 - test: revision 1 revision 1 ======= revision 2 >>>>>>> other: 0185f4e0cf02 - test: revision 2 space # hg stat M f ? f.orig # hg resolve --list U f simplest hgrc using false for merge: $ echo "false.whatever=" >> .hg/hgrc $ beforemerge [merge-tools] false.whatever= # hg update -C 1 $ hg merge -r 2 merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f #if unix-permissions unexecutable file in $PATH shouldn't be found: $ echo "echo fail" > false $ hg up -qC 1 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2 merging f warning: conflicts while merging f! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ rm false #endif executable directory in $PATH shouldn't be found: $ mkdir false $ hg up -qC 1 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2 merging f warning: conflicts while merging f! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ rmdir false true with higher .priority gets precedence: $ echo "true.priority=1" >> .hg/hgrc $ beforemerge [merge-tools] false.whatever= true.priority=1 # hg update -C 1 $ hg merge -r 2 merging f 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list R f unless lowered on command line: $ beforemerge [merge-tools] false.whatever= true.priority=1 # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.priority=-7 merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f or false set higher on command line: $ beforemerge [merge-tools] false.whatever= true.priority=1 # hg update -C 1 $ hg merge -r 2 --config merge-tools.false.priority=117 merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f or true set to disabled: $ beforemerge [merge-tools] false.whatever= true.priority=1 # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.disabled=yes merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f or true.executable not found in PATH: $ beforemerge [merge-tools] false.whatever= true.priority=1 # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.executable=nonexistentmergetool merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f or true.executable with bogus path: $ beforemerge [merge-tools] false.whatever= true.priority=1 # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.executable=/nonexistent/mergetool merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f but true.executable set to cat found in PATH works: $ echo "true.executable=cat" >> .hg/hgrc $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 merging f revision 1 space revision 0 space revision 2 space 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list R f and true.executable set to cat with path works: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.executable=cat merging f revision 1 space revision 0 space revision 2 space 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list R f #if unix-permissions environment variables in true.executable are handled: $ echo 'echo "custom merge tool"' > .hg/merge.sh $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg --config merge-tools.true.executable='sh' \ > --config merge-tools.true.args=.hg/merge.sh \ > merge -r 2 merging f custom merge tool 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list R f #endif Tool selection and merge-patterns merge-patterns specifies new tool false: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config merge-patterns.f=false merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f merge-patterns specifies executable not found in PATH and gets warning: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=nonexistentmergetool couldn't find merge tool true specified for f merging f couldn't find merge tool true specified for f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f merge-patterns specifies executable with bogus path and gets warning: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=/nonexistent/mergetool couldn't find merge tool true specified for f merging f couldn't find merge tool true specified for f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f ui.merge overrules priority ui.merge specifies false: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=false merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f ui.merge specifies internal:fail: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=internal:fail 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list U f ui.merge specifies :local (without internal prefix): $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=:local 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list R f ui.merge specifies internal:other: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=internal:other 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 2 space # hg stat M f # hg resolve --list R f ui.merge specifies internal:prompt: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=internal:prompt no tool found to merge f keep (l)ocal, take (o)ther, or leave (u)nresolved? u 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list U f ui.merge specifies :prompt, with 'leave unresolved' chosen $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=:prompt --config ui.interactive=True << EOF > u > EOF no tool found to merge f keep (l)ocal, take (o)ther, or leave (u)nresolved? u 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list U f prompt with EOF $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=internal:prompt --config ui.interactive=true no tool found to merge f keep (l)ocal, take (o)ther, or leave (u)nresolved? 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list U f $ hg resolve --all --config ui.merge=internal:prompt --config ui.interactive=true no tool found to merge f keep (l)ocal, take (o)ther, or leave (u)nresolved? [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f $ rm f $ hg resolve --all --config ui.merge=internal:prompt --config ui.interactive=true no tool found to merge f keep (l)ocal, take (o)ther, or leave (u)nresolved? [1] $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list U f $ hg resolve --all --config ui.merge=internal:prompt no tool found to merge f keep (l)ocal, take (o)ther, or leave (u)nresolved? u [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f ui.merge specifies internal:dump: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=internal:dump merging f 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.base ? f.local ? f.orig ? f.other # hg resolve --list U f f.base: $ cat f.base revision 0 space f.local: $ cat f.local revision 1 space f.other: $ cat f.other revision 2 space $ rm f.base f.local f.other ui.merge specifies internal:other but is overruled by pattern for false: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=internal:other --config merge-patterns.f=false merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f Premerge ui.merge specifies internal:other but is overruled by --tool=false $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=internal:other --tool=false merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f HGMERGE specifies internal:other but is overruled by --tool=false $ HGMERGE=internal:other ; export HGMERGE $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --tool=false merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f $ unset HGMERGE # make sure HGMERGE doesn't interfere with remaining tests update is a merge ... (this also tests that files reverted with '--rev REV' are treated as "modified", even if none of mode, size and timestamp of them isn't changed on the filesystem (see also issue4583)) $ cat >> $HGRCPATH <<EOF > [fakedirstatewritetime] > # emulate invoking dirstate.write() via repo.status() > # at 2000-01-01 00:00 > fakenow = 200001010000 > EOF $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg update -q 0 $ f -s f f: size=17 $ touch -t 200001010000 f $ hg debugrebuildstate $ cat >> $HGRCPATH <<EOF > [extensions] > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py > EOF $ hg revert -q -r 1 . $ cat >> $HGRCPATH <<EOF > [extensions] > fakedirstatewritetime = ! > EOF $ f -s f f: size=17 $ touch -t 200001010000 f $ hg status f M f $ hg update -r 2 merging f revision 1 space revision 0 space revision 2 space 0 files updated, 1 files merged, 0 files removed, 0 files unresolved $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list R f update should also have --tool $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg update -q 0 $ f -s f f: size=17 $ touch -t 200001010000 f $ hg debugrebuildstate $ cat >> $HGRCPATH <<EOF > [extensions] > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py > EOF $ hg revert -q -r 1 . $ cat >> $HGRCPATH <<EOF > [extensions] > fakedirstatewritetime = ! > EOF $ f -s f f: size=17 $ touch -t 200001010000 f $ hg status f M f $ hg update -r 2 --tool false merging f merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f Default is silent simplemerge: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 3 merging f 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space revision 3 # hg stat M f # hg resolve --list R f .premerge=True is same: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 3 --config merge-tools.true.premerge=True merging f 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space revision 3 # hg stat M f # hg resolve --list R f .premerge=False executes merge-tool: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 3 --config merge-tools.true.premerge=False merging f revision 1 space revision 0 space revision 0 space revision 3 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list R f premerge=keep keeps conflict markers in: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 4 --config merge-tools.true.premerge=keep merging f <<<<<<< local: ef83787e2614 - test: revision 1 revision 1 space ======= revision 4 >>>>>>> other: 81448d39c9a0 - test: revision 4 revision 0 space revision 4 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f <<<<<<< local: ef83787e2614 - test: revision 1 revision 1 space ======= revision 4 >>>>>>> other: 81448d39c9a0 - test: revision 4 # hg stat M f # hg resolve --list R f premerge=keep-merge3 keeps conflict markers with base content: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 4 --config merge-tools.true.premerge=keep-merge3 merging f <<<<<<< local: ef83787e2614 - test: revision 1 revision 1 space ||||||| base revision 0 space ======= revision 4 >>>>>>> other: 81448d39c9a0 - test: revision 4 revision 0 space revision 4 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f <<<<<<< local: ef83787e2614 - test: revision 1 revision 1 space ||||||| base revision 0 space ======= revision 4 >>>>>>> other: 81448d39c9a0 - test: revision 4 # hg stat M f # hg resolve --list R f Tool execution set tools.args explicit to include $base $local $other $output: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.executable=head --config merge-tools.true.args='$base $local $other $output' \ > | sed 's,==> .* <==,==> ... <==,g' merging f ==> ... <== revision 0 space ==> ... <== revision 1 space ==> ... <== revision 2 space ==> ... <== revision 1 space 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f revision 1 space # hg stat M f # hg resolve --list R f Merge with "echo mergeresult > $local": $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $local' merging f 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f mergeresult # hg stat M f # hg resolve --list R f - and $local is the file f: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > f' merging f 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f mergeresult # hg stat M f # hg resolve --list R f Merge with "echo mergeresult > $output" - the variable is a bit magic: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $output' merging f 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ aftermerge # cat f mergeresult # hg stat M f # hg resolve --list R f Merge using tool with a path that must be quoted: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ cat <<EOF > 'my merge tool' > cat "\$1" "\$2" "\$3" > "\$4" > EOF $ hg --config merge-tools.true.executable='sh' \ > --config merge-tools.true.args='"./my merge tool" $base $local $other $output' \ > merge -r 2 merging f 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ rm -f 'my merge tool' $ aftermerge # cat f revision 0 space revision 1 space revision 2 space # hg stat M f # hg resolve --list R f Issue3581: Merging a filename that needs to be quoted (This test doesn't work on Windows filesystems even on Linux, so check for Unix-like permission) #if unix-permissions $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ echo "revision 5" > '"; exit 1; echo "' $ hg commit -Am "revision 5" adding "; exit 1; echo " warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "' $ hg update -C 1 > /dev/null $ echo "revision 6" > '"; exit 1; echo "' $ hg commit -Am "revision 6" adding "; exit 1; echo " warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "' created new head $ hg merge --config merge-tools.true.executable="true" -r 5 merging "; exit 1; echo " 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg update -C 1 > /dev/null #endif Merge post-processing cat is a bad merge-tool and doesn't change: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -y -r 2 --config merge-tools.true.checkchanged=1 merging f revision 1 space revision 0 space revision 2 space output file f appears unchanged was merge successful (yn)? n merging f failed! 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] $ aftermerge # cat f revision 1 space # hg stat M f ? f.orig # hg resolve --list U f #if symlink internal merge cannot handle symlinks and shouldn't try: $ hg update -q -C 1 $ rm f $ ln -s symlink f $ hg commit -qm 'f is symlink' $ hg merge -r 2 --tool internal:merge merging f warning: internal :merge cannot merge symlinks for f warning: conflicts while merging f! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon [1] #endif