Patchwork D12116: merge-actions: add an explicite "no_op" attribute

login
register
mail settings
Submitter phabricator
Date Jan. 29, 2022, 2:15 p.m.
Message ID <differential-rev-PHID-DREV-amzw2jkgctwxxdd4sfqc-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/50441/
State New
Headers show

Comments

phabricator - Jan. 29, 2022, 2:15 p.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This make the MergeAction smarter and able to describe themself. This is useful
  to help introducing more MergeAction object that better the complexity of the
  situation.

REPOSITORY
  rHG Mercurial

BRANCH
  default

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

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

CHANGE DETAILS




To: marmoute, #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
@@ -396,7 +396,7 @@ 
             temporaryfiles.append(file)
             prunedactions[file] = action
         elif branchmerge:
-            if type not in mergestatemod.NO_OP_ACTIONS:
+            if not type.no_op:
                 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
@@ -105,13 +105,19 @@ 
     Attributes:
 
     _short: internal representation used to identify each action
+
+    no_op:  True if the action does affect the file content or tracking status
     """
 
     ALL_ACTIONS = weakref.WeakSet()
+    NO_OP_ACTIONS = weakref.WeakSet()
 
-    def __init__(self, short):
+    def __init__(self, short, no_op=False):
         self._short = short
         self.ALL_ACTIONS.add(self)
+        self.no_op = no_op
+        if self.no_op:
+            self.NO_OP_ACTIONS.add(self)
 
     def __hash__(self):
         return hash(self._short)
@@ -145,23 +151,17 @@ 
 ACTION_MERGE = MergeAction(b'm')
 ACTION_LOCAL_DIR_RENAME_GET = MergeAction(b'dg')
 ACTION_DIR_RENAME_MOVE_LOCAL = MergeAction(b'dm')
-ACTION_KEEP = MergeAction(b'k')
+ACTION_KEEP = MergeAction(b'k', no_op=True)
 # the file was absent on local side before merge and we should
 # keep it absent (absent means file not present, it can be a result
 # of file deletion, rename etc.)
-ACTION_KEEP_ABSENT = MergeAction(b'ka')
+ACTION_KEEP_ABSENT = MergeAction(b'ka', no_op=True)
 # 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 = MergeAction(b'kn')
+ACTION_KEEP_NEW = MergeAction(b'kn', no_op=True)
 ACTION_EXEC = MergeAction(b'e')
 ACTION_CREATED_MERGE = MergeAction(b'cm')
 
-# actions which are no op
-NO_OP_ACTIONS = (
-    ACTION_KEEP,
-    ACTION_KEEP_ABSENT,
-    ACTION_KEEP_NEW,
-)
 
 # Used by concert to detect situation it does not like, not sure what the exact
 # criteria is
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -527,7 +527,7 @@ 
             pass
         elif not branchmerge:
             mresult.removefile(f)  # just updating, ignore changes outside clone
-        elif action[0] in mergestatemod.NO_OP_ACTIONS:
+        elif action[0].no_op:
             mresult.removefile(f)  # merge does not affect file
         elif action[0] in nonconflicttypes:
             msg = _(
@@ -699,7 +699,7 @@ 
                     mergestatemod.ACTION_PATH_CONFLICT_RESOLVE,
                 )
                 and self._actionmapping[a]
-                and a not in mergestatemod.NO_OP_ACTIONS
+                and not a.no_op
             ):
                 return True
 
@@ -1520,7 +1520,8 @@ 
         # mergestate so that it can be reused on commit
         ms.addcommitinfo(f, op)
 
-    numupdates = mresult.len() - mresult.len(mergestatemod.NO_OP_ACTIONS)
+    num_no_op = mresult.len(mergestatemod.MergeAction.NO_OP_ACTIONS)
+    numupdates = mresult.len() - num_no_op
     progress = repo.ui.makeprogress(
         _(b'updating'), unit=_(b'files'), total=numupdates
     )
@@ -1624,7 +1625,7 @@ 
         progress.increment(item=f)
 
     # keep (noop, just log it)
-    for a in mergestatemod.NO_OP_ACTIONS:
+    for a in mergestatemod.MergeAction.NO_OP_ACTIONS:
         for f, args, msg in mresult.getactions((a,), sort=True):
             repo.ui.debug(b" %s: %s -> %s\n" % (f, msg, a.__bytes__()))
             # no progress