D777: merge: add merge action 'pr' to rename files during update

mbthomas (Mark Thomas) phabricator at mercurial-scm.org
Fri Sep 22 09:28:13 UTC 2017


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

REVISION SUMMARY
  Add a new merge action to handle a path conflict by renaming the conflicting
  file to a safe name.
  
  The rename is just to avoid problems on the filesystem.  The conflict is still
  considered unresolved until the user marks the original path as resolved.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/merge.py
  mercurial/sparse.py

CHANGE DETAILS

diff --git a/mercurial/sparse.py b/mercurial/sparse.py
--- a/mercurial/sparse.py
+++ b/mercurial/sparse.py
@@ -487,7 +487,7 @@
 
     # Apply changes to disk
     typeactions = dict((m, [])
-                       for m in 'a f g am cd dc r dm dg m e k p'.split())
+                       for m in 'a f g am cd dc r dm dg m e k p pr'.split())
     for f, (m, args, msg) in actions.iteritems():
         if m not in typeactions:
             typeactions[m] = []
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1261,14 +1261,26 @@
         z += 1
         progress(_updating, z, item=f, total=numupdates, unit=_files)
 
-    # remove in parallel (must come before getting)
+    # remove in parallel (must come before resolving path conflicts and getting)
     prog = worker.worker(repo.ui, 0.001, batchremove, (repo, wctx),
                          actions['r'])
     for i, item in prog:
         z += i
         progress(_updating, z, item=item, total=numupdates, unit=_files)
     removed = len(actions['r'])
 
+    # resolve path conflicts (must come before getting)
+    for f, args, msg in actions['pr']:
+        repo.ui.debug(" %s: %s -> pr\n" % (f, msg))
+        f0, = args
+        if wctx[f0].lexists():
+            repo.ui.note(_("moving %s to %s\n") % (f0, f))
+            wctx[f].audit()
+            wctx[f].write(wctx.filectx(f0).data(), wctx.filectx(f0).flags())
+            wctx[f0].remove()
+        z += 1
+        progress(_updating, z, item=f, total=numupdates, unit=_files)
+
     # We should flush before forking into worker processes, since those workers
     # flush when they complete, and we don't want to duplicate work.
     wctx.flushall()
@@ -1441,6 +1453,13 @@
     for f, args, msg in actions.get('f', []):
         repo.dirstate.drop(f)
 
+    # resolve path conflicts
+    for f, args, msg in actions.get('pr', []):
+        f0, = args
+        repo.dirstate.add(f)
+        repo.dirstate.remove(f0)
+        repo.dirstate.copy(f0, f)
+
     # re-add
     for f, args, msg in actions.get('a', []):
         repo.dirstate.add(f)
@@ -1672,7 +1691,7 @@
 
         if updatecheck == 'noconflict':
             for f, (m, args, msg) in actionbyfile.iteritems():
-                if m not in ('g', 'k', 'e', 'r'):
+                if m not in ('g', 'k', 'e', 'r', 'pr'):
                     msg = _("conflicting changes")
                     hint = _("commit or update --clean to discard changes")
                     raise error.Abort(msg, hint=hint)
@@ -1708,7 +1727,7 @@
 
         # Convert to dictionary-of-lists format
         actions = dict((m, [])
-                       for m in 'a am f g cd dc r dm dg m e k p'.split())
+                       for m in 'a am f g cd dc r dm dg m e k p pr'.split())
         for f, (m, args, msg) in actionbyfile.iteritems():
             if m not in actions:
                 actions[m] = []



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


More information about the Mercurial-devel mailing list