Patchwork [1,of,2,V3] mergestate: introduce a new ACTION_KEEP_NEW

login
register
mail settings
Submitter Pulkit Goyal
Date Sept. 23, 2020, 7:33 a.m.
Message ID <dad7218328fc44f0706f.1600846406@workspace>
Download mbox | patch
Permalink /patch/47244/
State Accepted
Headers show

Comments

Pulkit Goyal - Sept. 23, 2020, 7:33 a.m.
# HG changeset patch
# User Pulkit Goyal <7895pulkit@gmail.com>
# Date 1599650359 -19800
#      Wed Sep 09 16:49:19 2020 +0530
# Node ID dad7218328fc44f0706f9b6e33f3f9a50e439330
# Parent  e7587430ca239f3e7a148359063548b55415c919
# EXP-Topic merge-newnode
mergestate: introduce a new ACTION_KEEP_NEW

`ACTION_KEEP` is overloaded and it's hard to figure out how we end up with this
KEEP, what was the state of things.

In a previous patch, we introduced `ACTION_KEEP_ABSENT` which represents files
which are kept absent in the working directory.

There is another special case where we keep the file when it's not present on
both ancestor and remote side. We introduce a dedicated action for that.

The goal is to use these information to make bid merge smarter.

Differential Revision: https://phab.mercurial-scm.org/D9002
Yuya Nishihara - Sept. 23, 2020, 11:11 a.m.
On Wed, 23 Sep 2020 13:03:26 +0530, Pulkit Goyal wrote:
> # HG changeset patch
> # User Pulkit Goyal <7895pulkit@gmail.com>
> # Date 1599650359 -19800
> #      Wed Sep 09 16:49:19 2020 +0530
> # Node ID dad7218328fc44f0706f9b6e33f3f9a50e439330
> # Parent  e7587430ca239f3e7a148359063548b55415c919
> # EXP-Topic merge-newnode
> mergestate: introduce a new ACTION_KEEP_NEW

Queued, thanks.

>      # keep (noop, just log it)
> -    for f, args, msg in mresult.getactions(
> -        (mergestatemod.ACTION_KEEP,), sort=True
> -    ):
> -        repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
> -        # no progress
> -    for f, args, msg in mresult.getactions(
> -        (mergestatemod.ACTION_KEEP_ABSENT,), sort=True
> -    ):
> -        repo.ui.debug(b" %s: %s -> ka\n" % (f, msg))
> +    for a in mergeresult.NO_OP_ACTIONS:
> +        for f, args, msg in mresult.getactions((a,), sort=True):
> +            repo.ui.debug(b" %s: %s -> %s\n" % (f, msg, a))
>          # no progress
           ^^^^^^^^^^^^^
Fixed the indent level of the comment in flight.

Patch

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -552,6 +552,7 @@  class mergeresult(object):
     NO_OP_ACTIONS = (
         mergestatemod.ACTION_KEEP,
         mergestatemod.ACTION_KEEP_ABSENT,
+        mergestatemod.ACTION_KEEP_NEW,
     )
 
     def __init__(self):
@@ -921,7 +922,7 @@  def manifestmerge(
             else:  # file not in ancestor, not in remote
                 mresult.addfile(
                     f,
-                    mergestatemod.ACTION_KEEP,
+                    mergestatemod.ACTION_KEEP_NEW,
                     None,
                     b'ancestor missing, remote missing',
                 )
@@ -1191,6 +1192,11 @@  def calculateupdates(
                 repo.ui.note(_(b" %s: picking 'keep absent' action\n") % f)
                 mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_ABSENT][0])
                 continue
+            # If keep new is an option, let's just do that
+            if mergestatemod.ACTION_KEEP_NEW in bids:
+                repo.ui.note(_(b" %s: picking 'keep new' action\n") % f)
+                mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_NEW][0])
+                continue
             # If there are gets and they all agree [how could they not?], do it.
             if mergestatemod.ACTION_GET in bids:
                 ga0 = bids[mergestatemod.ACTION_GET][0]
@@ -1496,15 +1502,9 @@  def applyupdates(
         progress.increment(item=f)
 
     # keep (noop, just log it)
-    for f, args, msg in mresult.getactions(
-        (mergestatemod.ACTION_KEEP,), sort=True
-    ):
-        repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
-        # no progress
-    for f, args, msg in mresult.getactions(
-        (mergestatemod.ACTION_KEEP_ABSENT,), sort=True
-    ):
-        repo.ui.debug(b" %s: %s -> ka\n" % (f, msg))
+    for a in mergeresult.NO_OP_ACTIONS:
+        for f, args, msg in mresult.getactions((a,), sort=True):
+            repo.ui.debug(b" %s: %s -> %s\n" % (f, msg, a))
         # no progress
 
     # directory rename, move local
diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py
--- a/mercurial/mergestate.py
+++ b/mercurial/mergestate.py
@@ -117,6 +117,9 @@  ACTION_KEEP = b'k'
 # keep it absent (absent means file not present, it can be a result
 # of file deletion, rename etc.)
 ACTION_KEEP_ABSENT = b'ka'
+# the file is absent on the ancestor and remote side of the merge
+# hence this file is new and we should keep it
+ACTION_KEEP_NEW = b'kn'
 ACTION_EXEC = b'e'
 ACTION_CREATED_MERGE = b'cm'
 
@@ -767,6 +770,10 @@  def recordupdates(repo, actions, branchm
     for f, args, msg in actions.get(ACTION_KEEP_ABSENT, []):
         pass
 
+    # keep new
+    for f, args, msg in actions.get(ACTION_KEEP_NEW, []):
+        pass
+
     # get
     for f, args, msg in actions.get(ACTION_GET, []):
         if branchmerge:
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -431,8 +431,8 @@  Verify that the old context ancestor wor
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 11b5b303e36c, local: c0ef19750a22+, remote: 6ca01f7342b9
-   d1/a: ancestor missing, remote missing -> k
-   d1/b: ancestor missing, remote missing -> k
+   d1/a: ancestor missing, remote missing -> kn
+   d1/b: ancestor missing, remote missing -> kn
    d2/b: remote created -> g
   
   calculating bids for ancestor 154e6000f54e
@@ -452,13 +452,13 @@  Verify that the old context ancestor wor
   
   auction for merging merge bids (2 ancestors)
    list of bids for d1/a:
-     ancestor missing, remote missing -> k
+     ancestor missing, remote missing -> kn
      other deleted -> r
-   d1/a: picking 'keep' action
+   d1/a: picking 'keep new' action
    list of bids for d1/b:
-     ancestor missing, remote missing -> k
+     ancestor missing, remote missing -> kn
      other deleted -> r
-   d1/b: picking 'keep' action
+   d1/b: picking 'keep new' action
    list of bids for d2/b:
      remote created -> g
      remote created -> g
@@ -467,8 +467,8 @@  Verify that the old context ancestor wor
   
    d2/b: remote created -> g
   getting d2/b
-   d1/a: ancestor missing, remote missing -> k
-   d1/b: ancestor missing, remote missing -> k
+   d1/a: ancestor missing, remote missing -> kn
+   d1/b: ancestor missing, remote missing -> kn
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)