diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -578,21 +578,17 @@ % lfile ) if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile - mresult.actions[lfile] = (b'r', None, b'replaced by standin') - mresult.actions[standin] = (b'g', sargs, b'replaces standin') + mresult.addfile(lfile, b'r', None, b'replaced by standin') + mresult.addfile(standin, b'g', sargs, b'replaces standin') else: # keep local normal file - mresult.actions[lfile] = (b'k', None, b'replaces standin') + mresult.addfile(lfile, b'k', None, b'replaces standin') if branchmerge: - mresult.actions[standin] = ( - b'k', - None, - b'replaced by non-standin', + mresult.addfile( + standin, b'k', None, b'replaced by non-standin', ) else: - mresult.actions[standin] = ( - b'r', - None, - b'replaced by non-standin', + mresult.addfile( + standin, b'r', None, b'replaced by non-standin', ) elif lm in (b'g', b'dc') and sm != b'r': if lm == b'dc': @@ -611,29 +607,23 @@ if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile if branchmerge: # largefile can be restored from standin safely - mresult.actions[lfile] = ( - b'k', - None, - b'replaced by standin', + mresult.addfile( + lfile, b'k', None, b'replaced by standin', ) - mresult.actions[standin] = (b'k', None, b'replaces standin') + mresult.addfile(standin, b'k', None, b'replaces standin') else: # "lfile" should be marked as "removed" without # removal of itself - mresult.actions[lfile] = ( - b'lfmr', - None, - b'forget non-standin largefile', + mresult.addfile( + lfile, b'lfmr', None, b'forget non-standin largefile', ) # linear-merge should treat this largefile as 're-added' - mresult.actions[standin] = (b'a', None, b'keep standin') + mresult.addfile(standin, b'a', None, b'keep standin') else: # pick remote normal file - mresult.actions[lfile] = (b'g', largs, b'replaces standin') - mresult.actions[standin] = ( - b'r', - None, - b'replaced by non-standin', + mresult.addfile(lfile, b'g', largs, b'replaces standin') + mresult.addfile( + standin, b'r', None, b'replaced by non-standin', ) return mresult diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -561,12 +561,21 @@ self._renamedelete = {} self._commitinfo = {} - def updatevalues(self, actions, diverge, renamedelete, commitinfo): - self._actions = actions + def updatevalues(self, diverge, renamedelete, commitinfo): self._diverge = diverge self._renamedelete = renamedelete self._commitinfo = commitinfo + def addfile(self, filename, action, data, message): + """ adds a new file to the mergeresult object + + filename: file which we are adding + action: one of mergestatemod.ACTION_* + data: a tuple of information like fctx and ctx related to this merge + message: a message about the merge + """ + self._actions[filename] = (action, data, message) + @property def actions(self): return self._actions @@ -636,6 +645,7 @@ Returns an object of mergeresult class """ + mresult = mergeresult() if matcher is not None and matcher.always(): matcher = None @@ -700,7 +710,6 @@ diff = m1.diff(m2, match=matcher) - actions = {} for f, ((n1, fl1), (n2, fl2)) in pycompat.iteritems(diff): if n1 and n2: # file exists on both local and remote side if f not in ma: @@ -709,13 +718,15 @@ f, None ) or branch_copies2.copy.get(f, None) if fa is not None: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_MERGE, (f, f, fa, False, pa.node()), b'both renamed from %s' % fa, ) else: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_MERGE, (f, f, None, False, pa.node()), b'both created', @@ -725,20 +736,20 @@ fla = ma.flags(f) nol = b'l' not in fl1 + fl2 + fla if n2 == a and fl2 == fla: - actions[f] = ( - mergestatemod.ACTION_KEEP, - (), - b'remote unchanged', + mresult.addfile( + f, mergestatemod.ACTION_KEEP, (), b'remote unchanged', ) elif n1 == a and fl1 == fla: # local unchanged - use remote if n1 == n2: # optimization: keep local content - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_EXEC, (fl2,), b'update permissions', ) else: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_GET, (fl2, False), b'remote is newer', @@ -746,13 +757,15 @@ if branchmerge: commitinfo[f] = b'other' elif nol and n2 == a: # remote only changed 'x' - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_EXEC, (fl2,), b'update permissions', ) elif nol and n1 == a: # local only changed 'x' - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_GET, (fl1, False), b'remote is newer', @@ -760,7 +773,8 @@ if branchmerge: commitinfo[f] = b'other' else: # both changed something - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_MERGE, (f, f, f, False, pa.node()), b'versions differ', @@ -773,20 +787,23 @@ ): # directory rename, move local f2 = branch_copies1.movewithdir[f] if f2 in m2: - actions[f2] = ( + mresult.addfile( + f2, mergestatemod.ACTION_MERGE, (f, f2, None, True, pa.node()), b'remote directory rename, both created', ) else: - actions[f2] = ( + mresult.addfile( + f2, mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL, (f, fl1), b'remote directory rename - move from %s' % f, ) elif f in branch_copies1.copy: f2 = branch_copies1.copy[f] - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_MERGE, (f, f2, f2, False, pa.node()), b'local copied/moved from %s' % f2, @@ -794,13 +811,15 @@ elif f in ma: # clean, a different, no remote if n1 != ma[f]: if acceptremote: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_REMOVE, None, b'remote delete', ) else: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_CHANGED_DELETED, (f, None, f, False, pa.node()), b'prompt changed/deleted', @@ -808,16 +827,12 @@ elif n1 == addednodeid: # This file was locally added. We should forget it instead of # deleting it. - actions[f] = ( - mergestatemod.ACTION_FORGET, - None, - b'remote deleted', + mresult.addfile( + f, mergestatemod.ACTION_FORGET, None, b'remote deleted', ) else: - actions[f] = ( - mergestatemod.ACTION_REMOVE, - None, - b'other deleted', + mresult.addfile( + f, mergestatemod.ACTION_REMOVE, None, b'other deleted', ) elif n2: # file exists only on remote side if f in copied1: @@ -825,13 +840,15 @@ elif f in branch_copies2.movewithdir: f2 = branch_copies2.movewithdir[f] if f2 in m1: - actions[f2] = ( + mresult.addfile( + f2, mergestatemod.ACTION_MERGE, (f2, f, None, False, pa.node()), b'local directory rename, both created', ) else: - actions[f2] = ( + mresult.addfile( + f2, mergestatemod.ACTION_LOCAL_DIR_RENAME_GET, (f, fl2), b'local directory rename - get from %s' % f, @@ -839,13 +856,15 @@ elif f in branch_copies2.copy: f2 = branch_copies2.copy[f] if f2 in m2: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_MERGE, (f2, f, f2, False, pa.node()), b'remote copied from %s' % f2, ) else: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_MERGE, (f2, f, f2, True, pa.node()), b'remote moved from %s' % f2, @@ -863,19 +882,22 @@ # Checking whether the files are different is expensive, so we # don't do that when we can avoid it. if not force: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_CREATED, (fl2,), b'remote created', ) elif not branchmerge: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_CREATED, (fl2,), b'remote created', ) else: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_CREATED_MERGE, (fl2, pa.node()), b'remote created, get or merge', @@ -888,20 +910,23 @@ df = branch_copies1.dirmove[d] + f[len(d) :] break if df is not None and df in m1: - actions[df] = ( + mresult.addfile( + df, mergestatemod.ACTION_MERGE, (df, f, f, False, pa.node()), b'local directory rename - respect move ' b'from %s' % f, ) elif acceptremote: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_CREATED, (fl2,), b'remote recreating', ) else: - actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_DELETED_CHANGED, (None, f, f, False, pa.node()), b'prompt deleted/changed', @@ -909,18 +934,17 @@ if repo.ui.configbool(b'experimental', b'merge.checkpathconflicts'): # If we are merging, look for path conflicts. - checkpathconflicts(repo, wctx, p2, actions) + checkpathconflicts(repo, wctx, p2, mresult.actions) narrowmatch = repo.narrowmatch() if not narrowmatch.always(): # Updates "actions" in place - _filternarrowactions(narrowmatch, branchmerge, actions) + _filternarrowactions(narrowmatch, branchmerge, mresult.actions) renamedelete = branch_copies1.renamedelete renamedelete.update(branch_copies2.renamedelete) - mresult = mergeresult() - mresult.updatevalues(actions, diverge, renamedelete, commitinfo) + mresult.updatevalues(diverge, renamedelete, commitinfo) return mresult @@ -1046,7 +1070,7 @@ # Call for bids # Pick the best bid for each file repo.ui.note(_(b'\nauction for merging merge bids\n')) - actions = {} + mresult = mergeresult() for f, bids in sorted(fbids.items()): # bids is a mapping from action method to list af actions # Consensus? @@ -1054,19 +1078,19 @@ 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)) - actions[f] = l[0] + mresult.addfile(f, *l[0]) continue # If keep is an option, just do it. if mergestatemod.ACTION_KEEP in bids: repo.ui.note(_(b" %s: picking 'keep' action\n") % f) - actions[f] = bids[mergestatemod.ACTION_KEEP][0] + mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP][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] if all(a == ga0 for a in bids[mergestatemod.ACTION_GET][1:]): repo.ui.note(_(b" %s: picking 'get' action\n") % f) - actions[f] = ga0 + mresult.addfile(f, *ga0) continue # TODO: Consider other simple actions such as mode changes # Handle inefficient democrazy. @@ -1079,12 +1103,11 @@ repo.ui.warn( _(b' %s: ambiguous merge - picked %s action\n') % (f, m) ) - actions[f] = l[0] + mresult.addfile(f, *l[0]) continue repo.ui.note(_(b'end of auction\n\n')) # TODO: think about commitinfo when bid merge is used - mresult = mergeresult() - mresult.updatevalues(actions, diverge, renamedelete, {}) + mresult.updatevalues(diverge, renamedelete, {}) if wctx.rev() is None: fractions = _forgetremoved(wctx, mctx, branchmerge) @@ -1870,22 +1893,19 @@ % prompts, 0, ): - mresult.actions[f] = ( - mergestatemod.ACTION_REMOVE, - None, - b'prompt delete', + mresult.addfile( + f, mergestatemod.ACTION_REMOVE, None, b'prompt delete', ) elif f in p1: - mresult.actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_ADD_MODIFIED, None, b'prompt keep', ) else: - mresult.actions[f] = ( - mergestatemod.ACTION_ADD, - None, - b'prompt keep', + mresult.addfile( + f, mergestatemod.ACTION_ADD, None, b'prompt keep', ) elif m == mergestatemod.ACTION_DELETED_CHANGED: f1, f2, fa, move, anc = args @@ -1902,7 +1922,8 @@ ) == 0 ): - mresult.actions[f] = ( + mresult.addfile( + f, mergestatemod.ACTION_GET, (flags, False), b'prompt recreating',