Patchwork D8974: merge: add `ACTION_KEEP_DELETED` to represent files we want to keep deleted

login
register
mail settings
Submitter phabricator
Date Sept. 1, 2020, 12:14 p.m.
Message ID <differential-rev-PHID-DREV-3i2qecydhphn4dktlzk7-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47075/
State Superseded
Headers show

Comments

phabricator - Sept. 1, 2020, 12:14 p.m.
pulkit created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  There are files which were deleted/not present in working copy parent but were
  present on other side of merge. On merge, we might decide to keep them deleted.
  We want to track such cases more closely, rather all kind of cases which results
  from some kind of merging logic.
  
  We do have `ACTION_KEEP` but having a dedicated action for the deleted case is
  more cleaner.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

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

CHANGE DETAILS




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

Patch

diff --git a/mercurial/sparse.py b/mercurial/sparse.py
--- a/mercurial/sparse.py
+++ b/mercurial/sparse.py
@@ -399,7 +399,7 @@ 
             temporaryfiles.append(file)
             prunedactions[file] = action
         elif branchmerge:
-            if type != mergestatemod.ACTION_KEEP:
+            if type not in mergemod.mergeresult.NO_OP_ACTIONS:
                 temporaryfiles.append(file)
                 prunedactions[file] = action
         elif type == mergestatemod.ACTION_FORGET:
diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py
--- a/mercurial/mergestate.py
+++ b/mercurial/mergestate.py
@@ -120,6 +120,7 @@ 
 ACTION_LOCAL_DIR_RENAME_GET = b'dg'
 ACTION_DIR_RENAME_MOVE_LOCAL = b'dm'
 ACTION_KEEP = b'k'
+ACTION_KEEP_DELETED = b'kd'
 ACTION_EXEC = b'e'
 ACTION_CREATED_MERGE = b'cm'
 
@@ -837,6 +838,10 @@ 
     for f, args, msg in actions.get(ACTION_KEEP, []):
         pass
 
+    # keep deleted
+    for f, args, msg in actions.get(ACTION_KEEP_DELETED, []):
+        pass
+
     # get
     for f, args, msg in actions.get(ACTION_GET, []):
         if branchmerge:
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -523,7 +523,6 @@ 
     narrowed.
     """
     # TODO: handle with nonconflicttypes
-    nooptypes = {mergestatemod.ACTION_KEEP}
     nonconflicttypes = {
         mergestatemod.ACTION_ADD,
         mergestatemod.ACTION_ADD_MODIFIED,
@@ -541,7 +540,7 @@ 
             pass
         elif not branchmerge:
             mresult.removefile(f)  # just updating, ignore changes outside clone
-        elif action[0] in nooptypes:
+        elif action[0] in mergeresult.NO_OP_ACTIONS:
             mresult.removefile(f)  # merge does not affect file
         elif action[0] in nonconflicttypes:
             raise error.Abort(
@@ -564,6 +563,11 @@ 
     It has information about what actions need to be performed on dirstate
     mapping of divergent renames and other such cases. '''
 
+    NO_OP_ACTIONS = (
+        mergestatemod.ACTION_KEEP,
+        mergestatemod.ACTION_KEEP_DELETED,
+    )
+
     def __init__(self):
         """
         filemapping: dict of filename as keys and action related info as values
@@ -711,12 +715,12 @@ 
                 a
                 not in (
                     mergestatemod.ACTION_GET,
-                    mergestatemod.ACTION_KEEP,
                     mergestatemod.ACTION_EXEC,
                     mergestatemod.ACTION_REMOVE,
                     mergestatemod.ACTION_PATH_CONFLICT_RESOLVE,
                 )
                 and self._actionmapping[a]
+                and a not in self.NO_OP_ACTIONS
             ):
                 return True
 
@@ -1167,6 +1171,11 @@ 
                 repo.ui.note(_(b" %s: picking 'keep' action\n") % f)
                 mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP][0])
                 continue
+            # If keep deleted is an option, just do that
+            if mergestatemod.ACTION_KEEP_DELETED in bids:
+                repo.ui.note(_(b" %s: picking 'keep deleted' action\n") % f)
+                mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP_DELETED][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]
@@ -1412,7 +1421,7 @@ 
             wctx[f].audit()
             wctx[f].remove()
 
-    numupdates = mresult.len() - mresult.len((mergestatemod.ACTION_KEEP,))
+    numupdates = mresult.len() - mresult.len(mergeresult.NO_OP_ACTIONS)
     progress = repo.ui.makeprogress(
         _(b'updating'), unit=_(b'files'), total=numupdates
     )
@@ -1521,6 +1530,11 @@ 
     ):
         repo.ui.debug(b" %s: %s -> k\n" % (f, msg))
         # no progress
+    for f, args, msg in mresult.getactions(
+        (mergestatemod.ACTION_KEEP_DELETED,), sort=True
+    ):
+        repo.ui.debug(b" %s: %s -> kd\n" % (f, msg))
+        # no progress
 
     # directory rename, move local
     for f, args, msg in mresult.getactions(