view tests/test-merge-tools.t @ 12681:bc13e17067d9

update: use higher level wording for "crosses branches" error When using "hg update" to update to a revision on another branch, if the user has uncommitted changes in the working directory, hg aborts with the following message: abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes) If the user isn't trying to update to tip and they follow the command examples verbatim, they would end up updating to the wrong revision. This patch removes the command examples in favor of just telling the user to either merge or use --clean: abort: crosses branches (merge branches or use --clean to discard changes) hg also aborts if the user tries to use "hg update" to get to tip (without specifying a revision) and tip is on another branch: abort: crosses branches (use 'hg merge' or use 'hg update -c') This message is changed in the same fashion: abort: crosses branches (merge branches or use --check to force update)
author Brodie Rao <brodie@bitheap.org>
date Sat, 09 Oct 2010 17:02:28 -0500
parents 09168638b313
children de793925862e
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
  $ echo
  
  $ 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
  >   echo
  > }
  $ domerge() {
  >   beforemerge
  >   echo "# hg merge $*"
  >   hg merge $*
  >   aftermerge
  > }
  $ echo
  

Tool selection

  $ echo
  

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 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
  <<<<<<< local
  revision 1
  =======
  revision 2
  >>>>>>> other
  space
  # hg stat
  M f
  ? f.orig
  

simplest hgrc using false for merge:

  $ echo "false.whatever=" >> .hg/hgrc
  $ domerge -r 2
  [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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  

true with higher .priority gets precedence:

  $ echo "true.priority=1" >> .hg/hgrc
  $ domerge -r 2
  [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)
  # cat f
  revision 1
  space
  # hg stat
  M f
  

unless lowered on command line:

  $ domerge -r 2 --config merge-tools.true.priority=-7
  [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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  

or false set higher on command line:

  $ domerge -r 2 --config merge-tools.false.priority=117
  [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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  

or true.executable not found in PATH:

  $ domerge -r 2 --config merge-tools.true.executable=nonexistingmergetool
  [merge-tools]
  false.whatever=
  true.priority=1
  # hg update -C 1
  # hg merge -r 2 --config merge-tools.true.executable=nonexistingmergetool
  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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  

or true.executable with bogus path:

  $ domerge -r 2 --config merge-tools.true.executable=/nonexisting/mergetool
  [merge-tools]
  false.whatever=
  true.priority=1
  # hg update -C 1
  # hg merge -r 2 --config merge-tools.true.executable=/nonexisting/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
  # 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
  $ domerge -r 2
  [merge-tools]
  false.whatever=
  true.priority=1
  true.executable=cat
  # hg update -C 1
  # hg merge -r 2
  revision 1
  space
  revision 0
  space
  revision 2
  space
  merging f
  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  (branch merge, don't forget to commit)
  # cat f
  revision 1
  space
  # hg stat
  M f
  

and true.executable set to cat with path works:

  $ domerge -r 2 --config merge-tools.true.executable=cat
  [merge-tools]
  false.whatever=
  true.priority=1
  true.executable=cat
  # hg update -C 1
  # hg merge -r 2 --config merge-tools.true.executable=cat
  revision 1
  space
  revision 0
  space
  revision 2
  space
  merging f
  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  (branch merge, don't forget to commit)
  # cat f
  revision 1
  space
  # hg stat
  M f
  
  $ echo
  

Tool selection and merge-patterns

  $ echo
  

merge-patterns specifies new tool false:

  $ domerge -r 2 --config merge-patterns.f=false
  [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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  

merge-patterns specifies executable not found in PATH and gets warning:

  $ domerge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=nonexistingmergetool
  [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=nonexistingmergetool
  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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  

merge-patterns specifies executable with bogus path and gets warning:

  $ domerge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=/nonexisting/mergetool
  [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=/nonexisting/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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  
  $ echo
  

ui.merge overrules priority

  $ echo
  

ui.merge specifies false:

  $ domerge -r 2 --config ui.merge=false
  [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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  

ui.merge specifies internal:fail:

  $ domerge -r 2 --config ui.merge=internal:fail
  [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
  # cat f
  revision 1
  space
  # hg stat
  M f
  

ui.merge specifies internal:local:

  $ domerge -r 2 --config ui.merge=internal:local
  [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)
  # cat f
  revision 1
  space
  # hg stat
  M f
  

ui.merge specifies internal:other:

  $ domerge -r 2 --config ui.merge=internal:other
  [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)
  # cat f
  revision 2
  space
  # hg stat
  M f
  

ui.merge specifies internal:prompt:

  $ domerge -r 2 --config ui.merge=internal:prompt
  [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)
  # cat f
  revision 1
  space
  # hg stat
  M f
  

ui.merge specifies internal:dump:

  $ domerge -r 2 --config ui.merge=internal:dump
  [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
  # 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
  $ echo
  

ui.merge specifies internal:other but is overruled by pattern for false:

  $ domerge -r 2 --config ui.merge=internal:other --config merge-patterns.f=false
  [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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig
  
  $ echo
  

Premerge

  $ echo
  

Default is silent simplemerge:

  $ domerge -r 3
  [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)
  # cat f
  revision 1
  space
  revision 3
  # hg stat
  M f
  

.premerge=True is same:

  $ domerge -r 3 --config merge-tools.true.premerge=True
  [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)
  # cat f
  revision 1
  space
  revision 3
  # hg stat
  M f
  

.premerge=False executes merge-tool:

  $ domerge -r 3 --config merge-tools.true.premerge=False
  [merge-tools]
  false.whatever=
  true.priority=1
  true.executable=cat
  # hg update -C 1
  # hg merge -r 3 --config merge-tools.true.premerge=False
  revision 1
  space
  revision 0
  space
  revision 0
  space
  revision 3
  merging f
  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
  (branch merge, don't forget to commit)
  # cat f
  revision 1
  space
  # hg stat
  M f
  
  $ echo
  

Tool execution

  $ echo
  
  $ echo '# set tools.args explicit to include $base $local $other $output:' # default '$local $base $other'
  # 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'
  ==> ... <==
  revision 0
  space
  
  ==> ... <==
  revision 1
  space
  
  ==> ... <==
  revision 2
  space
  
  ==> ... <==
  revision 1
  space
  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
  
  $ echo '# Merge with "echo mergeresult > $local":'
  # 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
  
  $ echo '# - and $local is the file 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
  
  $ echo '# Merge with "echo mergeresult > $output" - the variable is a bit magic:'
  # 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'
  > #!/bin/sh
  > cat "\$1" "\$2" "\$3" > "\$4"
  > EOF
  $ chmod +x 'my merge tool'
  $ hg merge -r 2 --config merge-tools.true.executable='./my merge tool' --config merge-tools.true.args='$base $local $other $output'
  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
  
  $ echo
  

Merge post-processing

  $ echo
  

cat is a bad merge-tool and doesn't change:

  $ domerge -y -r 2 --config merge-tools.true.checkchanged=1
  [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
  revision 1
  space
  revision 0
  space
  revision 2
  space
  merging f
   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
  # cat f
  revision 1
  space
  # hg stat
  M f
  ? f.orig