merge-actions: add an explicite "no_op" attribute
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.
Differential Revision: https://phab.mercurial-scm.org/D12116
--- a/mercurial/merge.py Fri Jan 28 19:46:37 2022 +0100
+++ b/mercurial/merge.py Fri Jan 28 15:19:58 2022 +0100
@@ -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
--- a/mercurial/mergestate.py Fri Jan 28 19:46:37 2022 +0100
+++ b/mercurial/mergestate.py Fri Jan 28 15:19:58 2022 +0100
@@ -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
--- a/mercurial/sparse.py Fri Jan 28 19:46:37 2022 +0100
+++ b/mercurial/sparse.py Fri Jan 28 15:19:58 2022 +0100
@@ -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: