Patchwork D8930: mergestate: clear merge state if there are no unresolved conflicts

login
register
mail settings
Submitter phabricator
Date Aug. 18, 2020, 10:38 p.m.
Message ID <differential-rev-PHID-DREV-evtmxc6564nwlvvx3ese-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47031/
State Superseded
Headers show

Comments

phabricator - Aug. 18, 2020, 10:38 p.m.
martinvonz created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  After doing e.g. `hg update -m` and all files get automatically
  merged, we currently leave the merge state in place. That means that
  the previously checked-out commit node gets displayed as `%` in the
  log output. It also means that the user can re-resolve the files using
  `hg resolve`, possibly using a different merge tool. I can see some
  minor value in that, although I've never used it myself. However,
  commands that commit the changes right away (e.g. rebase, histedit,
  graft, backout, evolve) don't let the user re-resolve merged files
  without redoing the whole operation. I don't think we've had requests
  for that, either, so I don't think there's much reason to think that
  it is useful for operations that don't commit. This patch therefore
  makes us clear the mergestate if there are no unresolved conflicts.
  
  This has a large impact on the `test-merge-changedelete.t` test
  because that heavily exercised the re-resolve functionality.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

AFFECTED FILES
  mercurial/merge.py
  relnotes/next
  tests/test-merge-changedelete.t
  tests/test-merge-tools.t

CHANGE DETAILS




To: martinvonz, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-merge-tools.t b/tests/test-merge-tools.t
--- a/tests/test-merge-tools.t
+++ b/tests/test-merge-tools.t
@@ -1064,7 +1064,6 @@ 
   # hg stat
   M f
   # hg resolve --list
-  R f
 
 update should also have --tool
 
diff --git a/tests/test-merge-changedelete.t b/tests/test-merge-changedelete.t
--- a/tests/test-merge-changedelete.t
+++ b/tests/test-merge-changedelete.t
@@ -631,7 +631,7 @@ 
 
   $ testtransitions() {
   >     # this traversal order covers every transition
-  >     tools="local other prompt local fail other local prompt other fail prompt fail local"
+  >     tools="fail prompt fail"
   >     lasttool="merge3"
   >     for tool in $tools; do
   >         echo "=== :$lasttool -> :$tool ==="
@@ -649,67 +649,7 @@ 
   > }
 
   $ testtransitions
-  === :merge3 -> :local ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :local -> :other ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :other -> :prompt ===
-  file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
-  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
-  What do you want to do? 
-  file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
-  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
-  What do you want to do? 
-  file 'file3' needs to be resolved.
-  You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
-  What do you want to do? 
-  --- diff of status ---
-  (status identical)
-  
-  === :prompt -> :local ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :local -> :fail ===
-  --- diff of status ---
-  (status identical)
-  
-  === :fail -> :other ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :other -> :local ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :local -> :prompt ===
-  file 'file1' was deleted in other [merge rev] but was modified in local [working copy].
-  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
-  What do you want to do? 
-  file 'file2' was deleted in local [working copy] but was modified in other [merge rev].
-  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
-  What do you want to do? 
-  file 'file3' needs to be resolved.
-  You can keep (l)ocal [working copy], take (o)ther [merge rev], or leave (u)nresolved.
-  What do you want to do? 
-  --- diff of status ---
-  (status identical)
-  
-  === :prompt -> :other ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :other -> :fail ===
+  === :merge3 -> :fail ===
   --- diff of status ---
   (status identical)
   
@@ -730,11 +670,6 @@ 
   --- diff of status ---
   (status identical)
   
-  === :fail -> :local ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
 
 
 Non-interactive linear update
@@ -798,21 +733,8 @@ 
   A file1
   C file3
   --- resolve --list ---
-  R file1
-  R file2
   --- debugmergestate ---
-  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
-  file: file1 (state "r")
-    local path: file1 (hash 60b27f004e454aca81b0480209cce5081ec52390, flags "")
-    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node 0000000000000000000000000000000000000000)
-    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  file: file2 (state "r")
-    local path: file2 (hash 0000000000000000000000000000000000000000, flags "")
-    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
-    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  no merge state found
   --- file1 ---
   1
   changed
@@ -835,21 +757,8 @@ 
   C file2
   C file3
   --- resolve --list ---
-  R file1
-  R file2
   --- debugmergestate ---
-  local (working copy): ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  other (destination): 10f9a0a634e82080907e62f075ab119cbc565ea6
-  file: file1 (state "r")
-    local path: file1 (hash 60b27f004e454aca81b0480209cce5081ec52390, flags "")
-    ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
-    other path: file1 (node 0000000000000000000000000000000000000000)
-    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
-  file: file2 (state "r")
-    local path: file2 (hash 0000000000000000000000000000000000000000, flags "")
-    ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
-    other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
-    extra: ancestorlinknode = ab57bf49aa276a22d35a473592d4c34b5abc3eff
+  no merge state found
   *** file1 does not exist
   --- file2 ---
   2
@@ -997,61 +906,7 @@ 
 Test transitions between different merge tools
 
   $ testtransitions
-  === :merge3 -> :local ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :local -> :other ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :other -> :prompt ===
-  file 'file1' was deleted in other [destination] but was modified in local [working copy].
-  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
-  What do you want to do? 
-  file 'file2' was deleted in local [working copy] but was modified in other [destination].
-  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
-  What do you want to do? 
-  --- diff of status ---
-  (status identical)
-  
-  === :prompt -> :local ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :local -> :fail ===
-  --- diff of status ---
-  (status identical)
-  
-  === :fail -> :other ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :other -> :local ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :local -> :prompt ===
-  file 'file1' was deleted in other [destination] but was modified in local [working copy].
-  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
-  What do you want to do? 
-  file 'file2' was deleted in local [working copy] but was modified in other [destination].
-  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
-  What do you want to do? 
-  --- diff of status ---
-  (status identical)
-  
-  === :prompt -> :other ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
-  === :other -> :fail ===
+  === :merge3 -> :fail ===
   --- diff of status ---
   (status identical)
   
@@ -1069,8 +924,3 @@ 
   --- diff of status ---
   (status identical)
   
-  === :fail -> :local ===
-  (no more unresolved files)
-  --- diff of status ---
-  (status identical)
-  
diff --git a/relnotes/next b/relnotes/next
--- a/relnotes/next
+++ b/relnotes/next
@@ -16,6 +16,13 @@ 
 
 == Backwards Compatibility Changes ==
 
+ * If a command, such as `hg update -m`, automatically resolved all
+   conflicts, it used to still leave you with the merge state. You
+   could see that by running `hg resolve -l` (which would then show
+   only files marked with `R` for "resolved"). You could also see it
+   as a node in the graph log output showing `%`. This confused some
+   users. The merge state will now be cleared instead when all
+   conflicts were automatically resolved.
 
 
 == Internal API Changes ==
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -2057,6 +2057,9 @@ 
     # If we're updating to a location, clean up any stale temporary includes
     # (ex: this happens during hg rebase --abort).
     if not branchmerge:
+        if not stats.unresolvedcount:
+            ms = mergestatemod.mergestate.read(repo)
+            ms.reset()
         sparse.prunetemporaryincludes(repo)
 
     if updatedirstate: