[PATCH] merge: refuse update/merge if there are unresolved conflicts (BC)

Martin von Zweigbergk martinvonz at google.com
Tue Dec 8 22:59:41 UTC 2015


# HG changeset patch
# User Martin von Zweigbergk <martinvonz at google.com>
# Date 1449549804 28800
#      Mon Dec 07 20:43:24 2015 -0800
# Node ID 47cbf55690a528a93c9a07668b697164563befc8
# Parent  42aa0e570eaa364a622bc4443b0bcb79b1100a58
merge: refuse update/merge if there are unresolved conflicts (BC)

We currently allow updating and merging (with --force) when there are
unresolved merge conflicts, as long as there is only one parent of the
working copy. Even worse, when updating to another revision
(linearly), if one of the unresolved files (including any conflict
markers in the working copy) can now be merged cleanly with the target
revision, the file becomes marked as resolved.

While we could potentially allow updates that affect only files that
are not in the set of unresolved files, that's considerably more work,
and we don't have a use case for it anyway. Instead, let's keep it
simple and refuse any merge or update (without -C) when there are
unresolved conflicts.

Note that test-merge-local.t explicitly checks for conflict markers
that get carried over on update. It's unclear if that was intentional
or not, but it seems bad enough that we should forbid it. The simplest
way of fixing the test case is to leave the conflict markers in place
and just mark the files resolved, so let's just do that for now.

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1341,8 +1341,12 @@
         fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
 
         ### check phase
-        if not overwrite and len(pl) > 1:
-            raise error.Abort(_("outstanding uncommitted merge"))
+        if not overwrite:
+            if len(pl) > 1:
+                raise error.Abort(_("outstanding uncommitted merge"))
+            ms = mergestate.read(repo)
+            if list(ms.unresolved()):
+                raise error.Abort(_("outstanding merge conflicts"))
         if branchmerge:
             if pas == [p2]:
                 raise error.Abort(_("merging with a working directory ancestor"
diff --git a/tests/test-merge-local.t b/tests/test-merge-local.t
--- a/tests/test-merge-local.t
+++ b/tests/test-merge-local.t
@@ -59,6 +59,9 @@
   use 'hg resolve' to retry unresolved file merges
   [1]
 
+  $ hg resolve -m
+  (no more unresolved files)
+
   $ hg co 0
   merging zzz1_merge_ok
   merging zzz2_merge_bad
@@ -83,6 +86,9 @@
 
 Local merge with conflicts:
 
+  $ hg resolve -m
+  (no more unresolved files)
+
   $ hg co
   merging zzz1_merge_ok
   merging zzz2_merge_bad
@@ -91,6 +97,9 @@
   use 'hg resolve' to retry unresolved file merges
   [1]
 
+  $ hg resolve -m
+  (no more unresolved files)
+
   $ hg co 0 --config 'ui.origbackuppath=.hg/origbackups'
   merging zzz1_merge_ok
   merging zzz2_merge_bad
@@ -124,6 +133,9 @@
 
   $ hg revert zzz2_merge_bad
 
+  $ hg resolve -m
+  (no more unresolved files)
+
   $ hg co
   merging zzz1_merge_ok
   4 files updated, 1 files merged, 2 files removed, 0 files unresolved
diff --git a/tests/test-resolve.t b/tests/test-resolve.t
--- a/tests/test-resolve.t
+++ b/tests/test-resolve.t
@@ -154,6 +154,26 @@
   abort: resolve command not applicable when not merging
   [255]
 
+can not update or merge when there are unresolved conflicts
+
+  $ hg up -qC 0
+  $ echo quux >> file1
+  $ hg up 1
+  merging file1
+  warning: conflicts while merging file1! (edit, then use 'hg resolve --mark')
+  1 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges
+  [1]
+  $ hg up 0
+  abort: outstanding merge conflicts
+  [255]
+  $ hg merge 2
+  abort: outstanding merge conflicts
+  [255]
+  $ hg merge --force 2
+  abort: outstanding merge conflicts
+  [255]
+
 set up conflict-free merge
 
   $ hg up -qC 3


More information about the Mercurial-devel mailing list