evolve: merge commit messages while resolving content-divergence (issue5877)
authorPulkit Goyal <7895pulkit@gmail.com>
Mon, 04 Jun 2018 01:28:02 +0530
changeset 3801 ee78135b2f45
parent 3800 21914530c21c
child 3802 4bad80f1aad3
evolve: merge commit messages while resolving content-divergence (issue5877) While resolving content-divergence, there can be divergence in commit messages too which should be resolved. This patch uses the hg's internal merge API's to merge commit messages of divergent changesets with predecessor as the base. In case of conflicts, we fallback to divergent's commit message which should be changed in future. We should pop up the editor with the commit message and the conflict markers and let user fix that. Tests are added for the functionality added.
hgext3rd/evolve/evolvecmd.py
tests/test-evolve-content-divergence.t
--- a/hgext3rd/evolve/evolvecmd.py	Wed Jun 06 01:19:36 2018 +0530
+++ b/hgext3rd/evolve/evolvecmd.py	Mon Jun 04 01:28:02 2018 +0530
@@ -27,6 +27,7 @@
     phases,
     repair,
     scmutil,
+    simplemerge,
     util,
 )
 
@@ -485,10 +486,20 @@
                 elif index == 2:
                     repo.dirstate.setbranch(othbranch)
 
+        desc, conflicts = mergecommitmessages(base.description(),
+                                              divergent.description(),
+                                              other.description())
+        if conflicts:
+            # TODO: pop an editor when there are conflicts
+            ui.status(_("conflicts while merging descriptions, using "
+                        "description of divergent changeset\n"))
+            desc = divergent.description()
+
         # new node if any formed as the replacement
         newnode = None
+
         # XXX: we should not use amend here, rather create a new commit
-        cmdrewrite.amend(ui, repo, message='', logfile='')
+        cmdrewrite.amend(ui, repo, message=desc, logfile='')
         # XXX: we can get rid of this len() call also by creating a new commit
         if oldlen == len(repo):
             new = divergent
@@ -504,6 +515,21 @@
     finally:
         repo.ui.restoreconfig(emtpycommitallowed)
 
+def mergecommitmessages(basedesc, divdesc, othdesc):
+    """merges the commit messages and return the new merged message and whether
+    there were conflicts or not while merging the messages"""
+
+    merger = simplemerge.Merge3Text(basedesc, divdesc, othdesc)
+    mdesc = []
+    kwargs = {}
+    kwargs['name_base'] = 'base'
+    kwargs['base_marker'] = '|||||||'
+    for line in merger.merge_lines(name_a='divergent', name_b='other',
+                                   **kwargs):
+        mdesc.append(line)
+
+    return ''.join(mdesc), merger.conflicts
+
 class MergeFailure(error.Abort):
     pass
 
--- a/tests/test-evolve-content-divergence.t	Wed Jun 06 01:19:36 2018 +0530
+++ b/tests/test-evolve-content-divergence.t	Mon Jun 04 01:28:02 2018 +0530
@@ -27,8 +27,9 @@
   o  0:8fa14d15e168 added hgignore
       () [default] draft
 
-Creating content-divergence with branch change
-----------------------------------------------
+Creating content-divergence with branch change where base, divergent and other
+have different branches
+-------------------------------------------------------------------------------
 
   $ hg branch -r . foobar
   changed branch on 1 changesets
@@ -82,3 +83,176 @@
   |   () [default] draft
   o  0:8fa14d15e168 added hgignore
       () [default] draft
+
+Testing merging of commit messages
+-----------------------------------
+
+When base and one of the divergent has same commit messages and other divergent
+has different one
+
+  $ echo wat > d
+  $ hg amend
+
+  $ hg up .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+  $ echo bar > d
+  $ hg ci -Aqm "added a d with bar in it, expect some beers"
+
+  $ hg prune -r 23a4467c278e -s . --hidden
+  1 changesets pruned
+  2 new content-divergent changesets
+
+  $ hg glog
+  @  9:59081c9c425a added a d with bar in it, expect some beers
+  |   () [default] draft
+  | *  8:36618f77f252 added d
+  |/    () [foobar] draft
+  o  3:ca1b80f7960a added c
+  |   () [default] draft
+  o  2:b1661037fa25 added b
+  |   () [default] draft
+  o  1:c7586e2a9264 added a
+  |   () [default] draft
+  o  0:8fa14d15e168 added hgignore
+      () [default] draft
+
+  $ hg evolve --content-divergent
+  merge:[9] added a d with bar in it, expect some beers
+  with: [8] added d
+  base: [7] added d
+  merging "other" content-divergent changeset '36618f77f252'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at ca80aeaf4ee8
+
+  $ hg glog
+  @  10:ca80aeaf4ee8 added a d with bar in it, expect some beers
+  |   () [default] draft
+  o  3:ca1b80f7960a added c
+  |   () [default] draft
+  o  2:b1661037fa25 added b
+  |   () [default] draft
+  o  1:c7586e2a9264 added a
+  |   () [default] draft
+  o  0:8fa14d15e168 added hgignore
+      () [default] draft
+
+When base has different message and both divergents has same one
+
+  $ echo foo > d
+  $ hg amend -m "foo to d"
+
+  $ hg up ca80aeaf4ee8 --hidden
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  updated to hidden changeset ca80aeaf4ee8
+  (hidden revision 'ca80aeaf4ee8' was rewritten as: eba0b02801cb)
+  working directory parent is obsolete! (ca80aeaf4ee8)
+  (use 'hg evolve' to update to its successor: eba0b02801cb)
+  $ echo babar > d
+  $ hg amend -m "foo to d"
+  2 new content-divergent changesets
+
+  $ hg glog
+  @  12:0116315a1a4a foo to d
+  |   () [default] draft
+  | *  11:eba0b02801cb foo to d
+  |/    () [default] draft
+  o  3:ca1b80f7960a added c
+  |   () [default] draft
+  o  2:b1661037fa25 added b
+  |   () [default] draft
+  o  1:c7586e2a9264 added a
+  |   () [default] draft
+  o  0:8fa14d15e168 added hgignore
+      () [default] draft
+
+  $ hg evolve --content-divergent
+  merge:[12] foo to d
+  with: [11] foo to d
+  base: [10] added a d with bar in it, expect some beers
+  merging "other" content-divergent changeset 'eba0b02801cb'
+  merging d
+  warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  abort: fix conflicts and run 'hg evolve --continue' or use 'hg update -C .' to abort
+  [255]
+
+  $ echo foobar > d
+  $ hg resolve -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+  $ hg evolve --continue
+  working directory is now at 3e0a8df515d6
+
+  $ hg glog
+  @  13:3e0a8df515d6 foo to d
+  |   () [default] draft
+  o  3:ca1b80f7960a added c
+  |   () [default] draft
+  o  2:b1661037fa25 added b
+  |   () [default] draft
+  o  1:c7586e2a9264 added a
+  |   () [default] draft
+  o  0:8fa14d15e168 added hgignore
+      () [default] draft
+
+When all three base, divergent and other has different commit messages creating
+conflicts
+
+  $ echo bar > d
+  $ hg amend -m "bar to d, expect beers"
+
+  $ hg up 3e0a8df515d6 --hidden
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  updated to hidden changeset 3e0a8df515d6
+  (hidden revision '3e0a8df515d6' was rewritten as: 9ad4721c9004)
+  working directory parent is obsolete! (3e0a8df515d6)
+  (use 'hg evolve' to update to its successor: 9ad4721c9004)
+  $ echo wat > d
+  $ hg amend -m "wat to d, wat?"
+  2 new content-divergent changesets
+
+  $ hg glog
+  @  15:1e834b60df1b wat to d, wat?
+  |   () [default] draft
+  | *  14:9ad4721c9004 bar to d, expect beers
+  |/    () [default] draft
+  o  3:ca1b80f7960a added c
+  |   () [default] draft
+  o  2:b1661037fa25 added b
+  |   () [default] draft
+  o  1:c7586e2a9264 added a
+  |   () [default] draft
+  o  0:8fa14d15e168 added hgignore
+      () [default] draft
+
+  $ hg evolve --content-divergent
+  merge:[15] wat to d, wat?
+  with: [14] bar to d, expect beers
+  base: [13] foo to d
+  merging "other" content-divergent changeset '9ad4721c9004'
+  merging d
+  warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  abort: fix conflicts and run 'hg evolve --continue' or use 'hg update -C .' to abort
+  [255]
+
+  $ echo watbar > d
+  $ hg resolve -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+  $ hg evolve --continue
+  conflicts while merging descriptions, using description of divergent changeset
+  working directory is now at 578f12701e5a
+
+  $ hg glog
+  @  16:578f12701e5a wat to d, wat?
+  |   () [default] draft
+  o  3:ca1b80f7960a added c
+  |   () [default] draft
+  o  2:b1661037fa25 added b
+  |   () [default] draft
+  o  1:c7586e2a9264 added a
+  |   () [default] draft
+  o  0:8fa14d15e168 added hgignore
+      () [default] draft