[PATCH] merge: fast-forward merge with descendant

Mads Kiilerich mads at kiilerich.com
Mon Dec 6 20:35:42 CST 2010


# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1291688961 -3600
# Branch stable
# Node ID a68519c47a07b46392a29e486f0036ad42bc53dd
# Parent  acebcefa86d45560e271359663f9c0d9d5663573
merge: fast-forward merge with descendant

issue2538 gives a case where a changeset is merged with its child (which is on
another branch), and to my surprise the result is a real merge with two
parents, not just a "fast forward" "merge" with only the child as parent.

That is essentially the same as issue619.

Is the existing behaviour as intended and correct?

Or is the following fix correct?

Some extra "created new head" pops up with this fix, but it seems to me like
they could be considered correct. The old branch head has been superseeded by
changes on the other branch, and when the changes on the other branch is merged
back to the branch it will introduce a new head not directly related to the
previous branch head.

(I guess the intention with existing behaviour could be to ensure that the
changesets on the branch are directly connected and that no new heads pops up
on merges.)

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -524,7 +524,7 @@
         action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
 
         ### apply phase
-        if not branchmerge: # just jump to the new rev
+        if not branchmerge or fastforward: # just jump to the new rev
             fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
         if not partial:
             repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
@@ -533,7 +533,7 @@
 
         if not partial:
             repo.dirstate.setparents(fp1, fp2)
-            recordupdates(repo, action, branchmerge)
+            recordupdates(repo, action, branchmerge and not fastforward)
             if not branchmerge and not fastforward:
                 repo.dirstate.setbranch(p2.branch())
     finally:
diff --git a/tests/test-issue619.t b/tests/test-issue619.t
--- a/tests/test-issue619.t
+++ b/tests/test-issue619.t
@@ -19,7 +19,12 @@
   $ hg merge b
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
+  $ hg branch
+  default
+  $ hg parent --template '{rev}:{node|short} {branches}: {desc}\n'
+  1:06c2121185be b: b
   $ hg ci -Ammerge
+  created new head
 
 Bogus fast-forward should fail:
 
diff --git a/tests/test-newbranch.t b/tests/test-newbranch.t
--- a/tests/test-newbranch.t
+++ b/tests/test-newbranch.t
@@ -208,12 +208,11 @@
   $ hg branch
   foo
   $ hg commit -m'Merge ff into foo'
+  created new head
   $ hg parents
-  changeset:   6:917eb54e1b4b
+  changeset:   6:6af8030670c9
   branch:      foo
   tag:         tip
-  parent:      4:98d14f698afe
-  parent:      5:6683a60370cb
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     Merge ff into foo
diff --git a/tests/test-push-warn.t b/tests/test-push-warn.t
--- a/tests/test-push-warn.t
+++ b/tests/test-push-warn.t
@@ -396,6 +396,7 @@
   (branch merge, don't forget to commit)
 
   $ hg -R k ci -m merge
+  created new head
 
   $ hg -R k push -r a j
   pushing to j


More information about the Mercurial-devel mailing list