D5963: copies: handle the case when both merging csets are not descendant of merge base

khanchi97 (Sushil khanchi) phabricator at mercurial-scm.org
Thu Feb 14 14:15:55 UTC 2019


khanchi97 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Previous discussion on this issue can be found at this link:
  https://phab.mercurial-scm.org/D3896
  
  Copying description from previous patch sent by Pulkit:
  
  There can be cases when both the changesets which we are merging are not
  descendants of the merge base. In those cases dirtyc1 and dirtyc2 both will be
  true. The existing code assumes that either of them will be true always but that
  is not a right assumption.
  
  Pulkit found this while working with content-divergence resolution. In
  content-divergence resolution, we use the common predecessor as the merge base
  for resolving content divergence and there it can be possible that the merge
  base is not the descendant of both the content-divergence changsets.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5963

AFFECTED FILES
  mercurial/copies.py
  tests/test-copytrace-heuristics.t

CHANGE DETAILS

diff --git a/tests/test-copytrace-heuristics.t b/tests/test-copytrace-heuristics.t
--- a/tests/test-copytrace-heuristics.t
+++ b/tests/test-copytrace-heuristics.t
@@ -930,51 +930,28 @@
 
   $ hg graft -r 6 --base c9241b0f2d5b --hidden
   grafting 6:99802e4f1e46 "added willconflict and d" (tip)
-  ** unknown exception encountered, please report by visiting
-  ** https://mercurial-scm.org/wiki/BugTracker
-  ** Python 2.7.12 (default, Nov 12 2018, 14:36:49) [GCC 5.4.0 20160609]
-  ** Mercurial Distributed SCM (version 4.8.1+539-b6c610bf567e+20181221)
-  ** Extensions loaded: rebase, shelve
-  Traceback (most recent call last):
-    File "/home/khanchi/hg/hg-committed/hg", line 43, in <module>
-      dispatch.run()
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 99, in run
-      status = dispatch(req)
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 225, in dispatch
-      ret = _runcatch(req) or 0
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 376, in _runcatch
-      return _callcatch(ui, _runcatchfunc)
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 384, in _callcatch
-      return scmutil.callcatch(ui, func)
-    File "/home/khanchi/hg/hg-committed/mercurial/scmutil.py", line 165, in callcatch
-      return func()
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 367, in _runcatchfunc
-      return _dispatch(req)
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 1021, in _dispatch
-      cmdpats, cmdoptions)
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 756, in runcommand
-      ret = _runcommand(ui, options, cmd, d)
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 1030, in _runcommand
-      return cmdfunc()
-    File "/home/khanchi/hg/hg-committed/mercurial/dispatch.py", line 1018, in <lambda>
-      d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
-    File "/home/khanchi/hg/hg-committed/mercurial/util.py", line 1676, in check
-      return func(*args, **kwargs)
-    File "/home/khanchi/hg/hg-committed/mercurial/commands.py", line 2378, in graft
-      return _dograft(ui, repo, *revs, **opts)
-    File "/home/khanchi/hg/hg-committed/mercurial/commands.py", line 2590, in _dograft
-      stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
-    File "/home/khanchi/hg/hg-committed/mercurial/merge.py", line 2234, in graft
-      mergeancestor=mergeancestor, labels=labels)
-    File "/home/khanchi/hg/hg-committed/mercurial/merge.py", line 2075, in update
-      followcopies, matcher=matcher, mergeforce=mergeforce)
-    File "/home/khanchi/hg/hg-committed/mercurial/merge.py", line 1342, in calculateupdates
-      acceptremote, followcopies)
-    File "/home/khanchi/hg/hg-committed/mercurial/merge.py", line 1146, in manifestmerge
-      ret = copies.mergecopies(repo, wctx, p2, pa)
-    File "/home/khanchi/hg/hg-committed/mercurial/copies.py", line 416, in mergecopies
-      return _fullcopytracing(repo, c1, c2, base)
-    File "/home/khanchi/hg/hg-committed/mercurial/copies.py", line 568, in _fullcopytracing
-      assert not both2['incomplete']
-  AssertionError
-  [1]
+  merging willconflict
+  warning: conflicts while merging willconflict! (edit, then use 'hg resolve --mark')
+  abort: unresolved conflicts, can't continue
+  (use 'hg resolve' and 'hg graft --continue')
+  [255]
+
+  $ hg diff
+  diff -r 9a8bb7cc6814 willconflict
+  --- a/willconflict	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/willconflict	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,5 @@
+  +<<<<<<< local: 9a8bb7cc6814 - test: added c
+   foobar
+  +=======
+  +barfoo
+  +>>>>>>> graft: 99802e4f1e46 - test: added willconflict and d
+
+  $ echo barfoo > willconflict
+  $ hg resolve -m
+  (no more unresolved files)
+  continue: hg graft --continue
+  $ hg graft --continue
+  grafting 6:99802e4f1e46 "added willconflict and d" (tip)
+  $ cd ..
+  $ rm -rf repo
diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -524,7 +524,7 @@
     if dirtyc1:
         _combinecopies(data2['incomplete'], data1['incomplete'], copy, diverge,
                        incompletediverge)
-    else:
+    if dirtyc2:
         _combinecopies(data1['incomplete'], data2['incomplete'], copy, diverge,
                        incompletediverge)
 
@@ -563,7 +563,13 @@
     for f in bothnew:
         _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, both1)
         _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, both2)
-    if dirtyc1:
+    if dirtyc1 and dirtyc2:
+        remainder = _combinecopies(both2['incomplete'], both1['incomplete'],
+                                   copy, bothdiverge, bothincompletediverge)
+        remainder1 = _combinecopies(both1['incomplete'], both2['incomplete'],
+                                   copy, bothdiverge, bothincompletediverge)
+        remainder.update(remainder1)
+    elif dirtyc1:
         # incomplete copies may only be found on the "dirty" side for bothnew
         assert not both2['incomplete']
         remainder = _combinecopies({}, both1['incomplete'], copy, bothdiverge,



To: khanchi97, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list