# HG changeset patch # User Siddharth Agarwal # Date 2016-08-24 00:58:53 # Node ID 1316c7cccc76288274070c5f7dd68dd5dded2bec # Parent 92ac2baaea86dbba8565c359206fb97d39ec6e63 merge: remove files with extra actions from merge action list See the comment for a detailed explanation why. Even though this is a bug, I've sent it to 'default' rather than 'stable' because it isn't triggered in any code paths in stock Mercurial, just with the merge driver included. For the same reason I haven't included any tests here -- the merge driver is getting a new test. diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1286,8 +1286,29 @@ def applyupdates(repo, actions, wctx, mc removed += msremoved extraactions = ms.actions() - for k, acts in extraactions.iteritems(): - actions[k].extend(acts) + if extraactions: + mfiles = set(a[0] for a in actions['m']) + for k, acts in extraactions.iteritems(): + actions[k].extend(acts) + # Remove these files from actions['m'] as well. This is important + # because in recordupdates, files in actions['m'] are processed + # after files in other actions, and the merge driver might add + # files to those actions via extraactions above. This can lead to a + # file being recorded twice, with poor results. This is especially + # problematic for actions['r'] (currently only possible with the + # merge driver in the initial merge process; interrupted merges + # don't go through this flow). + # + # The real fix here is to have indexes by both file and action so + # that when the action for a file is changed it is automatically + # reflected in the other action lists. But that involves a more + # complex data structure, so this will do for now. + # + # We don't need to do the same operation for 'dc' and 'cd' because + # those lists aren't consulted again. + mfiles.difference_update(a[0] for a in acts) + + actions['m'] = [a for a in actions['m'] if a[0] in mfiles] progress(_updating, None, total=numupdates, unit=_files)