branch: allow changing branch of merge commits with --rev
authorAnton Shestakov <av6@dwimlabs.net>
Fri, 09 Nov 2018 13:57:13 +0800
changeset 40666 69268a13ffa5
parent 40665 fb379b78b93e
child 40667 02318e0810ac
branch: allow changing branch of merge commits with --rev Tests show that changing branch of merge commits works fine with evolution and without, so let's allow it. Other safeguards should prevent users from shooting themselves in the foot.
mercurial/cmdutil.py
tests/test-branch-change.t
--- a/mercurial/cmdutil.py	Thu Nov 15 22:28:38 2018 -0500
+++ b/mercurial/cmdutil.py	Fri Nov 09 13:57:13 2018 +0800
@@ -732,11 +732,10 @@
         rewriteutil.precheck(repo, revs, 'change branch of')
 
         root = repo[roots.first()]
-        if not root.p1().branch() == label and label in repo.branchmap():
+        rpb = {parent.branch() for parent in root.parents()}
+        if label not in rpb and label in repo.branchmap():
             raise error.Abort(_("a branch of the same name already exists"))
 
-        if repo.revs('merge() and %ld', revs):
-            raise error.Abort(_("cannot change branch of a merge commit"))
         if repo.revs('obsolete() and %ld', revs):
             raise error.Abort(_("cannot change branch of a obsolete changeset"))
 
--- a/tests/test-branch-change.t	Thu Nov 15 22:28:38 2018 -0500
+++ b/tests/test-branch-change.t	Fri Nov 09 13:57:13 2018 +0800
@@ -308,24 +308,116 @@
   o  18:204d2769eca2 Added a
      stable ()
 
-Testing on merge
+Changing branch of a merge commit
 
-  $ hg merge -r 26
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg branch -q ghi
+  $ echo f > f
+  $ hg ci -qAm 'Added f'
+  $ hg up -q 27
+  $ hg branch -q jkl
+  $ echo g > g
+  $ hg ci -qAm 'Added g'
+  $ hg glog -r 'heads(:)'
+  @  29:6bc1c6c2c9da Added g
+  |  jkl ()
+  ~
+  o  28:2f1019bd29d2 Added f
+  |  ghi (b1)
+  ~
+
+  $ hg branch -q default
+  $ hg merge -r 28
+  4 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
-
   $ hg branch -r . abcd
   abort: outstanding uncommitted merge
   [255]
+
   $ hg ci -m "Merge commit"
-  $ hg branch -r '(.^)::' def
-  abort: cannot change branch of a merge commit
+  $ hg glog -r 'parents(.)::'
+  @    30:4d56e6b1eb6b Merge commit
+  |\   default ()
+  | o  29:6bc1c6c2c9da Added g
+  | |  jkl ()
+  | ~
+  o  28:2f1019bd29d2 Added f
+  |  ghi (b1)
+  ~
+
+  $ hg branch -r . ghi
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  changed branch on 1 changesets
+  $ hg branch -r . jkl
+  changed branch on 1 changesets
+  $ hg branch -r . default
+  changed branch on 1 changesets
+  $ hg branch -r . stable
+  abort: a branch of the same name already exists
   [255]
 
 Changing branch on public changeset
 
-  $ hg phase -r 27 -p
-  $ hg branch -r 27 def
+  $ hg phase -r . -p
+  $ hg branch -r . def
   abort: cannot change branch of public changesets
   (see 'hg help phases' for details)
   [255]
+
+Merge commit with conflicts, with evolution and without
+
+  $ mklozenge() {
+  >   echo foo > a
+  >   hg ci -qAm foo
+  >   echo bar > a
+  >   hg ci -qm bar
+  >   hg up -q '.^'
+  >   echo baz > a
+  >   hg ci -qm baz
+  >   hg merge -q -t :local
+  >   echo neither > a
+  >   hg ci -qm neither
+  > }
+
+  $ cd ..
+  $ hg init merge-with-evolution
+  $ cd merge-with-evolution
+  $ mklozenge
+
+  $ hg branch -r '(.^)::' abc
+  changed branch on 2 changesets
+  $ hg glog
+  @    5:c07fa8b34d54 neither
+  |\   abc ()
+  | o  4:f2aa51777cc9 baz
+  | |  abc ()
+  o |  1:2e33c4f0856b bar
+  |/   default ()
+  o  0:91cfb6004abf foo
+     default ()
+  $ hg cat a
+  neither
+
+  $ cd ..
+  $ hg init merge-without-evolution
+  $ cd merge-without-evolution
+  $ mklozenge
+  $ cat > .hg/hgrc << EOF
+  > [experimental]
+  > evolution = no
+  > evolution.allowunstable = no
+  > EOF
+
+  $ hg branch -r '(.^)::' abc
+  changed branch on 2 changesets
+  saved backup bundle to $TESTTMP/merge-without-evolution/.hg/strip-backup/9a3a2af368f4-8db1a361-branch-change.hg
+  $ hg glog
+  @    3:c07fa8b34d54 neither
+  |\   abc ()
+  | o  2:f2aa51777cc9 baz
+  | |  abc ()
+  o |  1:2e33c4f0856b bar
+  |/   default ()
+  o  0:91cfb6004abf foo
+     default ()
+  $ hg cat a
+  neither