Mercurial > hg
view tests/test-merge-tools.t @ 20182:04036798ebed
branches: avoid unnecessary changectx.branch() calls
This requires reading from the changelog, which can be costly over NFS.
Note that this does not totally remove reading from the changelog; we
still do that when calling changectx.closesbranch(). That call will be
removed in a later patch.
Running hg branches on the PyPy repo (with 996) over a busy NFS server,
before this change:
$ time hg --profile branches > /dev/null
CallCount Recursive Total(s) Inline(s) module:lineno(function)
2042 0 2.2827 2.2827 <open>
2036 0 0.9840 0.9840 <method 'close' of 'file' objects>
2036 0 0.0464 0.0464 <method 'read' of 'file' objects>
5233 0 0.1985 0.0453 mercurial.repoview:161(changelog)
10462 0 0.0791 0.0314 mercurial.changelog:133(tip)
5233 0 0.0388 0.0176 mercurial.localrepo:26(__get__)
10462 0 0.0250 0.0126 <len>
5233 0 0.0059 0.0039 mercurial.repoview:112(filterrevs)
10462 0 0.0029 0.0029 <hash>
2034 0 0.0444 0.0444 <method 'seek' of 'file' objects>
5340 0 0.0390 0.0390 mercurial.revlog:296(rev)
2582 0 0.0371 0.0371 <zlib.decompress>
3155 0 0.1963 0.0366 mercurial.context:202(__init__)
3155 0 0.1238 0.0306 mercurial.repoview:161(changelog)
3155 0 0.0261 0.0080 mercurial.changelog:183(rev)
9465 0 0.0061 0.0061 <isinstance>
1096 0 0.0023 0.0023 <binascii.unhexlify>
4251 0 0.0014 0.0014 <len>
2059 0 3.7341 0.0332 mercurial.changelog:270(read)
2059 0 3.6304 0.0307 mercurial.revlog:907(revision)
2057 0 0.0262 0.0137 mercurial.changelog:28(decodeextra)
4118 0 0.0094 0.0094 <method 'split' of 'str' objects>
4118 0 0.0270 0.0048 mercurial.encoding:61(tolocal)
2059 0 0.0040 0.0040 <method 'index' of 'str' objects>
10462 0 0.0791 0.0314 mercurial.changelog:133(tip)
10462 0 0.0289 0.0207 mercurial.changelog:190(node)
10462 0 0.0188 0.0091 <len>
52433 20932 0.0478 0.0310 <len>
20932 0 0.0221 0.0168 mercurial.revlog:262(__len__)
2059 0 3.6304 0.0307 mercurial.revlog:907(revision)
real 0m4.361s
user 0m0.986s
sys 0m0.237s
After this change:
$ time hg --profile branches > /dev/null
CallCount Recursive Total(s) Inline(s) module:lineno(function)
1069 0 1.1098 1.1098 <open>
1063 0 0.4865 0.4865 <method 'close' of 'file' objects>
4122 0 0.1811 0.0404 mercurial.repoview:161(changelog)
8240 0 0.0712 0.0272 mercurial.changelog:133(tip)
4122 0 0.0378 0.0177 mercurial.localrepo:26(__get__)
8240 0 0.0221 0.0115 <len>
4122 0 0.0057 0.0033 mercurial.repoview:112(filterrevs)
8240 0 0.0025 0.0025 <hash>
3029 0 0.1979 0.0371 mercurial.context:202(__init__)
3029 0 0.1278 0.0310 mercurial.repoview:161(changelog)
3029 0 0.0230 0.0081 mercurial.changelog:183(rev)
9087 0 0.0061 0.0061 <isinstance>
1096 0 0.0026 0.0026 <binascii.unhexlify>
4125 0 0.0014 0.0014 <len>
4229 0 0.0337 0.0337 mercurial.revlog:296(rev)
1061 0 0.0296 0.0296 <method 'seek' of 'file' objects>
1063 0 0.0292 0.0292 <method 'read' of 'file' objects>
8240 0 0.0712 0.0272 mercurial.changelog:133(tip)
8240 0 0.0271 0.0196 mercurial.changelog:190(node)
8240 0 0.0169 0.0083 <len>
40476 16488 0.0422 0.0271 <len>
16488 0 0.0193 0.0152 mercurial.revlog:262(__len__)
1342 0 0.0241 0.0241 <zlib.decompress>
9445 0 0.0336 0.0224 mercurial.changelog:190(node)
9445 0 0.0112 0.0112 mercurial.revlog:317(node)
1074 0 1.9102 0.0224 mercurial.changelog:270(read)
1074 0 1.8397 0.0202 mercurial.revlog:907(revision)
1073 0 0.0187 0.0099 mercurial.changelog:28(decodeextra)
2148 0 0.0061 0.0061 <method 'split' of 'str' objects>
2148 0 0.0184 0.0034 mercurial.encoding:61(tolocal)
real 0m2.402s
user 0m0.735s
sys 0m0.177s
author | Brodie Rao <brodie@sf.io> |
---|---|
date | Fri, 15 Nov 2013 23:18:08 -0500 |
parents | eac114e13b96 |
children | 25d5a9ecbb85 |
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 $ 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 > 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" $PYTHON "$BINDIR"/hg merge -r 2 merging f warning: conflicts during merge. merging f incomplete! (edit conflicts, 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 revision 1 ======= revision 2 >>>>>>> other space # hg stat M f ? f.orig 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 unexecutable file in $PATH shouldn't be found: $ touch false $ hg up -qC 1 $ PATH="`pwd`:$BINDIR" $PYTHON "$BINDIR"/hg merge -r 2 merging f warning: conflicts during merge. merging f incomplete! (edit conflicts, 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 executable directory in $PATH shouldn't be found: $ mkdir false $ hg up -qC 1 $ PATH="`pwd`:$BINDIR" $PYTHON "$BINDIR"/hg merge -r 2 merging f warning: conflicts during merge. merging f incomplete! (edit conflicts, 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 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 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 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 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 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 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 #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 #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 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 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 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 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 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 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 ui.merge specifies internal:local: $ beforemerge [merge-tools] false.whatever= true.priority=1 true.executable=cat # hg update -C 1 $ hg merge -r 2 --config ui.merge=internal: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 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 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 or take (o)ther? l 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 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 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 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 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 $ unset HGMERGE # make sure HGMERGE doesn't interfere with remaining tests 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 .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 .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 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 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 - 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 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 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 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 4" > '"; exit 1; echo "' $ hg commit -Am "revision 4" adding "; exit 1; echo " warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "' $ hg update -C 1 > /dev/null $ 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 "' created new head $ hg merge --config merge-tools.true.executable="true" -r 4 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 #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 merging f incomplete! (edit conflicts, 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