# HG changeset patch # User Pierre-Yves David # Date 2022-01-28 16:08:30 # Node ID 9bc86adf32f685f924de80c3e23084653c866a56 # Parent b0aa9b0b9c21cbd39f15b937d063bfd4000a32ad merge-actions: make merge action a full featured object This open the way for having "smarter" value as action, making the usage code simpler and more flexible. We have to explicitly use __bytes__ call in a couple of place because Python2… Differential Revision: https://phab.mercurial-scm.org/D12114 diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -61,7 +61,7 @@ eh = exthelper.exthelper() lfstatus = lfutil.lfstatus -MERGE_ACTION_LARGEFILE_MARK_REMOVED = b'lfmr' +MERGE_ACTION_LARGEFILE_MARK_REMOVED = mergestatemod.MergeAction('lfmr') # -- Utility functions: commonly/repeatedly needed functionality --------------- diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1201,7 +1201,7 @@ def calculateupdates( for f, a in mresult1.filemap(sort=True): m, args, msg = a - repo.ui.debug(b' %s: %s -> %s\n' % (f, msg, m)) + repo.ui.debug(b' %s: %s -> %s\n' % (f, msg, m.__bytes__())) if f in fbids: d = fbids[f] if m in d: @@ -1222,13 +1222,15 @@ def calculateupdates( repo.ui.debug(b" list of bids for %s:\n" % f) for m, l in sorted(bids.items()): for _f, args, msg in l: - repo.ui.debug(b' %s -> %s\n' % (msg, m)) + repo.ui.debug(b' %s -> %s\n' % (msg, m.__bytes__())) # bids is a mapping from action method to list af actions # Consensus? if len(bids) == 1: # all bids are the same kind of method m, l = list(bids.items())[0] if all(a == l[0] for a in l[1:]): # len(bids) is > 1 - repo.ui.note(_(b" %s: consensus for %s\n") % (f, m)) + repo.ui.note( + _(b" %s: consensus for %s\n") % (f, m.__bytes__()) + ) mresult.addfile(f, *l[0]) continue # If keep is an option, just do it. @@ -1286,11 +1288,12 @@ def calculateupdates( repo.ui.note(_(b' %s: multiple bids for merge action:\n') % f) for m, l in sorted(bids.items()): for _f, args, msg in l: - repo.ui.note(b' %s -> %s\n' % (msg, m)) + repo.ui.note(b' %s -> %s\n' % (msg, m.__bytes__())) # Pick random action. TODO: Instead, prompt user when resolving m, l = list(bids.items())[0] repo.ui.warn( - _(b' %s: ambiguous merge - picked %s action\n') % (f, m) + _(b' %s: ambiguous merge - picked %s action\n') + % (f, m.__bytes__()) ) mresult.addfile(f, *l[0]) continue @@ -1623,7 +1626,7 @@ def applyupdates( # keep (noop, just log it) for a in mergestatemod.NO_OP_ACTIONS: for f, args, msg in mresult.getactions((a,), sort=True): - repo.ui.debug(b" %s: %s -> %s\n" % (f, msg, a)) + repo.ui.debug(b" %s: %s -> %s\n" % (f, msg, a.__bytes__())) # no progress # directory rename, move local diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py --- a/mercurial/mergestate.py +++ b/mercurial/mergestate.py @@ -98,29 +98,59 @@ LEGACY_MERGE_DRIVER_STATE = b'm' LEGACY_MERGE_DRIVER_MERGE = b'D' -ACTION_FORGET = b'f' -ACTION_REMOVE = b'r' -ACTION_ADD = b'a' -ACTION_GET = b'g' -ACTION_PATH_CONFLICT = b'p' -ACTION_PATH_CONFLICT_RESOLVE = b'pr' -ACTION_ADD_MODIFIED = b'am' -ACTION_CREATED = b'c' -ACTION_DELETED_CHANGED = b'dc' -ACTION_CHANGED_DELETED = b'cd' -ACTION_MERGE = b'm' -ACTION_LOCAL_DIR_RENAME_GET = b'dg' -ACTION_DIR_RENAME_MOVE_LOCAL = b'dm' -ACTION_KEEP = b'k' +class MergeAction(object): + """represent an "action" merge need to take for a given file + + Attributes: + + _short: internal representation used to identify each action + """ + + def __init__(self, short): + self._short = short + + def __hash__(self): + return hash(self._short) + + def __repr__(self): + return 'MergeAction<%s>' % self._short.decode('ascii') + + def __bytes__(self): + return self._short + + def __eq__(self, other): + if other is None: + return False + assert isinstance(other, MergeAction) + return self._short == other._short + + def __lt__(self, other): + return self._short < other._short + + +ACTION_FORGET = MergeAction(b'f') +ACTION_REMOVE = MergeAction(b'r') +ACTION_ADD = MergeAction(b'a') +ACTION_GET = MergeAction(b'g') +ACTION_PATH_CONFLICT = MergeAction(b'p') +ACTION_PATH_CONFLICT_RESOLVE = MergeAction('pr') +ACTION_ADD_MODIFIED = MergeAction(b'am') +ACTION_CREATED = MergeAction(b'c') +ACTION_DELETED_CHANGED = MergeAction(b'dc') +ACTION_CHANGED_DELETED = MergeAction(b'cd') +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') # 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 = b'ka' +ACTION_KEEP_ABSENT = MergeAction(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' +ACTION_KEEP_NEW = MergeAction(b'kn') +ACTION_EXEC = MergeAction(b'e') +ACTION_CREATED_MERGE = MergeAction(b'cm') # actions which are no op NO_OP_ACTIONS = (