Patchwork [4,of,8] merge: change debug logging and progress

login
register
mail settings
Submitter Mads Kiilerich
Date May 1, 2014, 11:42 p.m.
Message ID <feac4ee682bea8ebb19e.1398987772@mk-desktop>
Download mbox | patch
Permalink /patch/4469/
State Superseded
Headers show

Comments

Mads Kiilerich - May 1, 2014, 11:42 p.m.
# HG changeset patch
# User Mads Kiilerich <madski@unity3d.com>
# Date 1398125425 -7200
#      Tue Apr 22 02:10:25 2014 +0200
# Branch stable
# Node ID feac4ee682bea8ebb19ead775bdb9ef413da8e3e
# Parent  28162b4271a8a4c4cdee6532c49aa5316f9133d5
merge: change debug logging and progress

Preparing for action list split-up ...
Pierre-Yves David - May 7, 2014, 9:07 p.m.
On 05/01/2014 04:42 PM, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich <madski@unity3d.com>
> # Date 1398125425 -7200
> #      Tue Apr 22 02:10:25 2014 +0200
> # Branch stable
> # Node ID feac4ee682bea8ebb19ead775bdb9ef413da8e3e
> # Parent  28162b4271a8a4c4cdee6532c49aa5316f9133d5
> merge: change debug logging and progress
>
> Preparing for action list split-up ...

Description is not very helpful

>
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -571,9 +571,9 @@ def getremove(repo, mctx, overwrite, arg
>       wwrite = repo.wwrite
>       audit = repo.wopener.audit
>       i = 0
> -    for arg in args:
> -        f = arg[0]
> -        if arg[1] == 'r':
> +    for f, m, args, msg in args:
> +        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
> +        if m == 'r':
>               if verbose:
>                   repo.ui.note(_("removing %s\n") % f)
>               audit(f)
> @@ -585,7 +585,7 @@ def getremove(repo, mctx, overwrite, arg
>           else:
>               if verbose:
>                   repo.ui.note(_("getting %s\n") % f)
> -            wwrite(f, fctx(f).data(), arg[2][0])
> +            wwrite(f, fctx(f).data(), args[0])
>           if i == 100:
>               yield i, f
>               i = 0
> @@ -612,12 +612,11 @@ def applyupdates(repo, actions, wctx, mc
>       # prescan for merges
>       for a in actions:
>           f, m, args, msg = a
> -        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
>           if m == "m": # merge
>               f1, f2, fa, move, anc = args
>               if f == '.hgsubstate': # merged internally
>                   continue
> -            repo.ui.debug("  preserving %s for resolve of %s\n" % (f1, f))
> +            repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))

unexpected space change?


>               fcl = wctx[f1]
>               fco = mctx[f2]
>               actx = repo[anc]
> @@ -647,7 +646,7 @@ def applyupdates(repo, actions, wctx, mc
>       updated = len(updateactions)
>       removeactions = [a for a in workeractions if a[1] == 'r']
>       removed = len(removeactions)
> -    actions = [a for a in actions if a[1] not in 'grk']
> +    actions = [a for a in actions if a[1] not in 'gr']
>
>       hgsub = [a[1] for a in workeractions if a[0] == '.hgsubstate']
>       if hgsub and hgsub[0] == 'r':
> @@ -671,10 +670,30 @@ def applyupdates(repo, actions, wctx, mc
>       if hgsub and hgsub[0] == 'g':
>           subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
>
> -    for i, a in enumerate(actions):
> -        f, m, args, msg = a
> -        progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files)
> -        if m == "m": # merge
> +    for f, m, args, msg in actions:
> +
> +        # forget (manifest only, just log it) (must come first)
> +        if m == "f":
> +            repo.ui.debug(" %s: %s -> f\n" % (f, msg))
> +            z += 1
> +            progress(_updating, z, item=f, total=numupdates, unit=_files)
> +
> +        # re-add (manifest only, just log it)
> +        elif m == "a":
> +            repo.ui.debug(" %s: %s -> a\n" % (f, msg))
> +            z += 1
> +            progress(_updating, z, item=f, total=numupdates, unit=_files)
> +
> +        # keep (noop, just log it)
> +        elif m == "k":
> +            repo.ui.debug(" %s: %s -> k\n" % (f, msg))
> +            # no progress
> +
> +        # merge
> +        elif m == "m":
> +            repo.ui.debug(" %s: %s -> m\n" % (f, msg))
> +            z += 1
> +            progress(_updating, z, item=f, total=numupdates, unit=_files)

Those almost identical and repeated call to ui.debug(…) are bugging me. 
Can't we factor them?

>               f1, f2, fa, move, anc = args
>               if f == '.hgsubstate': # subrepo states need updating
>                   subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
> @@ -689,35 +708,61 @@ def applyupdates(repo, actions, wctx, mc
>                       updated += 1
>                   else:
>                       merged += 1
> -        elif m == "dm": # directory rename, move local
> +
> +        # directory rename, move local
> +        elif m == "dm":
> +            repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
> +            z += 1
> +            progress(_updating, z, item=f, total=numupdates, unit=_files)
>               f0, flags = args
>               repo.ui.note(_("moving %s to %s\n") % (f0, f))
>               audit(f)
>               repo.wwrite(f, wctx.filectx(f0).data(), flags)
>               util.unlinkpath(repo.wjoin(f0))
>               updated += 1
> -        elif m == "dg": # local directory rename, get
> +
> +        # local directory rename, get
> +        elif m == "dg":
> +            repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
> +            z += 1
> +            progress(_updating, z, item=f, total=numupdates, unit=_files)
>               f0, flags = args
>               repo.ui.note(_("getting %s to %s\n") % (f0, f))
>               repo.wwrite(f, mctx.filectx(f0).data(), flags)
>               updated += 1
> -        elif m == "dr": # divergent renames
> +
> +        # divergent renames
> +        elif m == "dr":
> +            repo.ui.debug(" %s: %s -> dr\n" % (f, msg))
> +            z += 1
> +            progress(_updating, z, item=f, total=numupdates, unit=_files)
>               fl, = args
>               repo.ui.warn(_("note: possible conflict - %s was renamed "
>                              "multiple times to:\n") % f)
>               for nf in fl:
>                   repo.ui.warn(" %s\n" % nf)
> -        elif m == "rd": # rename and delete
> +
> +        # rename and delete
> +        elif m == "rd":
> +            repo.ui.debug(" %s: %s -> rd\n" % (f, msg))
> +            z += 1
> +            progress(_updating, z, item=f, total=numupdates, unit=_files)
>               fl, = args
>               repo.ui.warn(_("note: possible conflict - %s was deleted "
>                              "and renamed to:\n") % f)
>               for nf in fl:
>                   repo.ui.warn(" %s\n" % nf)
> -        elif m == "e": # exec
> +
> +        # exec
> +        elif m == "e":
> +            repo.ui.debug(" %s: %s -> e\n" % (f, msg))
> +            z += 1
> +            progress(_updating, z, item=f, total=numupdates, unit=_files)
>               flags, = args
>               audit(f)
>               util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
>               updated += 1
> +
>       ms.commit()
>       progress(_updating, None, total=numupdates, unit=_files)
>
> @@ -744,7 +789,7 @@ def calculateupdates(repo, wctx, mctx, a
>               actions = manifestmerge(repo, wctx, mctx, ancestor,
>                                       branchmerge, force,
>                                       partial, acceptremote, followcopies)
> -            for a in sorted(actions):
> +            for a in sorted(actions, key=lambda a: (a[1], a)):

New obscure key added to the sorted call?
Mads Kiilerich - May 8, 2014, 11:33 a.m.
On 05/07/2014 11:07 PM, Pierre-Yves David wrote:
>
>
> On 05/01/2014 04:42 PM, Mads Kiilerich wrote:
>> # HG changeset patch
>> # User Mads Kiilerich <madski@unity3d.com>
>> # Date 1398125425 -7200
>> #      Tue Apr 22 02:10:25 2014 +0200
>> # Branch stable
>> # Node ID feac4ee682bea8ebb19ead775bdb9ef413da8e3e
>> # Parent  28162b4271a8a4c4cdee6532c49aa5316f9133d5
>> merge: change debug logging and progress
>>
>> Preparing for action list split-up ...
>
> Description is not very helpful

There is not much to say. The patch moves debug statements around 
without really changing anything. Arguably, it temporarily makes the 
code worse. Then only justification is that it makes it easier to review 
the test changes ... and in the end the 8th don't change test output at all.

>
>>
>> diff --git a/mercurial/merge.py b/mercurial/merge.py
>> --- a/mercurial/merge.py
>> +++ b/mercurial/merge.py
>> @@ -571,9 +571,9 @@ def getremove(repo, mctx, overwrite, arg
>>       wwrite = repo.wwrite
>>       audit = repo.wopener.audit
>>       i = 0
>> -    for arg in args:
>> -        f = arg[0]
>> -        if arg[1] == 'r':
>> +    for f, m, args, msg in args:
>> +        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
>> +        if m == 'r':
>>               if verbose:
>>                   repo.ui.note(_("removing %s\n") % f)
>>               audit(f)
>> @@ -585,7 +585,7 @@ def getremove(repo, mctx, overwrite, arg
>>           else:
>>               if verbose:
>>                   repo.ui.note(_("getting %s\n") % f)
>> -            wwrite(f, fctx(f).data(), arg[2][0])
>> +            wwrite(f, fctx(f).data(), args[0])
>>           if i == 100:
>>               yield i, f
>>               i = 0
>> @@ -612,12 +612,11 @@ def applyupdates(repo, actions, wctx, mc
>>       # prescan for merges
>>       for a in actions:
>>           f, m, args, msg = a
>> -        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
>>           if m == "m": # merge
>>               f1, f2, fa, move, anc = args
>>               if f == '.hgsubstate': # merged internally
>>                   continue
>> -            repo.ui.debug("  preserving %s for resolve of %s\n" % 
>> (f1, f))
>> +            repo.ui.debug(" preserving %s for resolve of %s\n" % 
>> (f1, f))
>
> unexpected space change?

Not really. The debug statement will no longer have the single space 
indented "->" before it. Having this message double indented will thus 
no longer make sense.

>
>
>>               fcl = wctx[f1]
>>               fco = mctx[f2]
>>               actx = repo[anc]
>> @@ -647,7 +646,7 @@ def applyupdates(repo, actions, wctx, mc
>>       updated = len(updateactions)
>>       removeactions = [a for a in workeractions if a[1] == 'r']
>>       removed = len(removeactions)
>> -    actions = [a for a in actions if a[1] not in 'grk']
>> +    actions = [a for a in actions if a[1] not in 'gr']
>>
>>       hgsub = [a[1] for a in workeractions if a[0] == '.hgsubstate']
>>       if hgsub and hgsub[0] == 'r':
>> @@ -671,10 +670,30 @@ def applyupdates(repo, actions, wctx, mc
>>       if hgsub and hgsub[0] == 'g':
>>           subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
>>
>> -    for i, a in enumerate(actions):
>> -        f, m, args, msg = a
>> -        progress(_updating, z + i + 1, item=f, total=numupdates, 
>> unit=_files)
>> -        if m == "m": # merge
>> +    for f, m, args, msg in actions:
>> +
>> +        # forget (manifest only, just log it) (must come first)
>> +        if m == "f":
>> +            repo.ui.debug(" %s: %s -> f\n" % (f, msg))
>> +            z += 1
>> +            progress(_updating, z, item=f, total=numupdates, 
>> unit=_files)
>> +
>> +        # re-add (manifest only, just log it)
>> +        elif m == "a":
>> +            repo.ui.debug(" %s: %s -> a\n" % (f, msg))
>> +            z += 1
>> +            progress(_updating, z, item=f, total=numupdates, 
>> unit=_files)
>> +
>> +        # keep (noop, just log it)
>> +        elif m == "k":
>> +            repo.ui.debug(" %s: %s -> k\n" % (f, msg))
>> +            # no progress
>> +
>> +        # merge
>> +        elif m == "m":
>> +            repo.ui.debug(" %s: %s -> m\n" % (f, msg))
>> +            z += 1
>> +            progress(_updating, z, item=f, total=numupdates, 
>> unit=_files)
>
> Those almost identical and repeated call to ui.debug(…) are bugging 
> me. Can't we factor them?

Look at how it is after the 8th patch where we gain code readability and 
efficiency. It is possible that we could introduce a "process this 
action list and do some logging and progress reporting and apply this 
function" later.

>
>>               f1, f2, fa, move, anc = args
>>               if f == '.hgsubstate': # subrepo states need updating
>>                   subrepo.submerge(repo, wctx, mctx, 
>> wctx.ancestor(mctx),
>> @@ -689,35 +708,61 @@ def applyupdates(repo, actions, wctx, mc
>>                       updated += 1
>>                   else:
>>                       merged += 1
>> -        elif m == "dm": # directory rename, move local
>> +
>> +        # directory rename, move local
>> +        elif m == "dm":
>> +            repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
>> +            z += 1
>> +            progress(_updating, z, item=f, total=numupdates, 
>> unit=_files)
>>               f0, flags = args
>>               repo.ui.note(_("moving %s to %s\n") % (f0, f))
>>               audit(f)
>>               repo.wwrite(f, wctx.filectx(f0).data(), flags)
>>               util.unlinkpath(repo.wjoin(f0))
>>               updated += 1
>> -        elif m == "dg": # local directory rename, get
>> +
>> +        # local directory rename, get
>> +        elif m == "dg":
>> +            repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
>> +            z += 1
>> +            progress(_updating, z, item=f, total=numupdates, 
>> unit=_files)
>>               f0, flags = args
>>               repo.ui.note(_("getting %s to %s\n") % (f0, f))
>>               repo.wwrite(f, mctx.filectx(f0).data(), flags)
>>               updated += 1
>> -        elif m == "dr": # divergent renames
>> +
>> +        # divergent renames
>> +        elif m == "dr":
>> +            repo.ui.debug(" %s: %s -> dr\n" % (f, msg))
>> +            z += 1
>> +            progress(_updating, z, item=f, total=numupdates, 
>> unit=_files)
>>               fl, = args
>>               repo.ui.warn(_("note: possible conflict - %s was renamed "
>>                              "multiple times to:\n") % f)
>>               for nf in fl:
>>                   repo.ui.warn(" %s\n" % nf)
>> -        elif m == "rd": # rename and delete
>> +
>> +        # rename and delete
>> +        elif m == "rd":
>> +            repo.ui.debug(" %s: %s -> rd\n" % (f, msg))
>> +            z += 1
>> +            progress(_updating, z, item=f, total=numupdates, 
>> unit=_files)
>>               fl, = args
>>               repo.ui.warn(_("note: possible conflict - %s was deleted "
>>                              "and renamed to:\n") % f)
>>               for nf in fl:
>>                   repo.ui.warn(" %s\n" % nf)
>> -        elif m == "e": # exec
>> +
>> +        # exec
>> +        elif m == "e":
>> +            repo.ui.debug(" %s: %s -> e\n" % (f, msg))
>> +            z += 1
>> +            progress(_updating, z, item=f, total=numupdates, 
>> unit=_files)
>>               flags, = args
>>               audit(f)
>>               util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
>>               updated += 1
>> +
>>       ms.commit()
>>       progress(_updating, None, total=numupdates, unit=_files)
>>
>> @@ -744,7 +789,7 @@ def calculateupdates(repo, wctx, mctx, a
>>               actions = manifestmerge(repo, wctx, mctx, ancestor,
>>                                       branchmerge, force,
>>                                       partial, acceptremote, 
>> followcopies)
>> -            for a in sorted(actions):
>> +            for a in sorted(actions, key=lambda a: (a[1], a)):
>
> New obscure key added to the sorted call?

It is only temporary so the convoluted code gives the same output as the 
simplified code will do in step 8.

/Mads
Pierre-Yves David - May 8, 2014, 7:56 p.m.
On 05/08/2014 04:33 AM, Mads Kiilerich wrote:
> On 05/07/2014 11:07 PM, Pierre-Yves David wrote:
>>
>>
>> On 05/01/2014 04:42 PM, Mads Kiilerich wrote:
>>> # HG changeset patch
>>> # User Mads Kiilerich <madski@unity3d.com>
>>> # Date 1398125425 -7200
>>> #      Tue Apr 22 02:10:25 2014 +0200
>>> # Branch stable
>>> # Node ID feac4ee682bea8ebb19ead775bdb9ef413da8e3e
>>> # Parent  28162b4271a8a4c4cdee6532c49aa5316f9133d5
>>> merge: change debug logging and progress
>>>
>>> Preparing for action list split-up ...
>>
>> Description is not very helpful
>
> There is not much to say. The patch moves debug statements around
> without really changing anything. Arguably, it temporarily makes the
> code worse. Then only justification is that it makes it easier to review
> the test changes ... and in the end the 8th don't change test output at
> all.

That already a significant amount said. It should be in the commit 
description in the first place.

>
>>
>>>
>>> diff --git a/mercurial/merge.py b/mercurial/merge.py
>>> --- a/mercurial/merge.py
>>> +++ b/mercurial/merge.py
>>> @@ -571,9 +571,9 @@ def getremove(repo, mctx, overwrite, arg
>>>       wwrite = repo.wwrite
>>>       audit = repo.wopener.audit
>>>       i = 0
>>> -    for arg in args:
>>> -        f = arg[0]
>>> -        if arg[1] == 'r':
>>> +    for f, m, args, msg in args:
>>> +        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
>>> +        if m == 'r':
>>>               if verbose:
>>>                   repo.ui.note(_("removing %s\n") % f)
>>>               audit(f)
>>> @@ -585,7 +585,7 @@ def getremove(repo, mctx, overwrite, arg
>>>           else:
>>>               if verbose:
>>>                   repo.ui.note(_("getting %s\n") % f)
>>> -            wwrite(f, fctx(f).data(), arg[2][0])
>>> +            wwrite(f, fctx(f).data(), args[0])
>>>           if i == 100:
>>>               yield i, f
>>>               i = 0
>>> @@ -612,12 +612,11 @@ def applyupdates(repo, actions, wctx, mc
>>>       # prescan for merges
>>>       for a in actions:
>>>           f, m, args, msg = a
>>> -        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
>>>           if m == "m": # merge
>>>               f1, f2, fa, move, anc = args
>>>               if f == '.hgsubstate': # merged internally
>>>                   continue
>>> -            repo.ui.debug("  preserving %s for resolve of %s\n" %
>>> (f1, f))
>>> +            repo.ui.debug(" preserving %s for resolve of %s\n" %
>>> (f1, f))
>>
>> unexpected space change?
>
> Not really. The debug statement will no longer have the single space
> indented "->" before it. Having this message double indented will thus
> no longer make sense.

Ha!, documentation of output change that should have been in the 
description.

>>>               fcl = wctx[f1]
>>>               fco = mctx[f2]
>>>               actx = repo[anc]
>>> @@ -647,7 +646,7 @@ def applyupdates(repo, actions, wctx, mc
>>>       updated = len(updateactions)
>>>       removeactions = [a for a in workeractions if a[1] == 'r']
>>>       removed = len(removeactions)
>>> -    actions = [a for a in actions if a[1] not in 'grk']
>>> +    actions = [a for a in actions if a[1] not in 'gr']
>>>
>>>       hgsub = [a[1] for a in workeractions if a[0] == '.hgsubstate']
>>>       if hgsub and hgsub[0] == 'r':
>>> @@ -671,10 +670,30 @@ def applyupdates(repo, actions, wctx, mc
>>>       if hgsub and hgsub[0] == 'g':
>>>           subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
>>>
>>> -    for i, a in enumerate(actions):
>>> -        f, m, args, msg = a
>>> -        progress(_updating, z + i + 1, item=f, total=numupdates,
>>> unit=_files)
>>> -        if m == "m": # merge
>>> +    for f, m, args, msg in actions:
>>> +
>>> +        # forget (manifest only, just log it) (must come first)
>>> +        if m == "f":
>>> +            repo.ui.debug(" %s: %s -> f\n" % (f, msg))
>>> +            z += 1
>>> +            progress(_updating, z, item=f, total=numupdates,
>>> unit=_files)
>>> +
>>> +        # re-add (manifest only, just log it)
>>> +        elif m == "a":
>>> +            repo.ui.debug(" %s: %s -> a\n" % (f, msg))
>>> +            z += 1
>>> +            progress(_updating, z, item=f, total=numupdates,
>>> unit=_files)
>>> +
>>> +        # keep (noop, just log it)
>>> +        elif m == "k":
>>> +            repo.ui.debug(" %s: %s -> k\n" % (f, msg))
>>> +            # no progress
>>> +
>>> +        # merge
>>> +        elif m == "m":
>>> +            repo.ui.debug(" %s: %s -> m\n" % (f, msg))
>>> +            z += 1
>>> +            progress(_updating, z, item=f, total=numupdates,
>>> unit=_files)
>>
>> Those almost identical and repeated call to ui.debug(…) are bugging
>> me. Can't we factor them?
>
> Look at how it is after the 8th patch where we gain code readability and
> efficiency. It is possible that we could introduce a "process this
> action list and do some logging and progress reporting and apply this
> function" later.

Ok, please justify this in the description too.


>
>>
>>>               f1, f2, fa, move, anc = args
>>>               if f == '.hgsubstate': # subrepo states need updating
>>>                   subrepo.submerge(repo, wctx, mctx,
>>> wctx.ancestor(mctx),
>>> @@ -689,35 +708,61 @@ def applyupdates(repo, actions, wctx, mc
>>>                       updated += 1
>>>                   else:
>>>                       merged += 1
>>> -        elif m == "dm": # directory rename, move local
>>> +
>>> +        # directory rename, move local
>>> +        elif m == "dm":
>>> +            repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
>>> +            z += 1
>>> +            progress(_updating, z, item=f, total=numupdates,
>>> unit=_files)
>>>               f0, flags = args
>>>               repo.ui.note(_("moving %s to %s\n") % (f0, f))
>>>               audit(f)
>>>               repo.wwrite(f, wctx.filectx(f0).data(), flags)
>>>               util.unlinkpath(repo.wjoin(f0))
>>>               updated += 1
>>> -        elif m == "dg": # local directory rename, get
>>> +
>>> +        # local directory rename, get
>>> +        elif m == "dg":
>>> +            repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
>>> +            z += 1
>>> +            progress(_updating, z, item=f, total=numupdates,
>>> unit=_files)
>>>               f0, flags = args
>>>               repo.ui.note(_("getting %s to %s\n") % (f0, f))
>>>               repo.wwrite(f, mctx.filectx(f0).data(), flags)
>>>               updated += 1
>>> -        elif m == "dr": # divergent renames
>>> +
>>> +        # divergent renames
>>> +        elif m == "dr":
>>> +            repo.ui.debug(" %s: %s -> dr\n" % (f, msg))
>>> +            z += 1
>>> +            progress(_updating, z, item=f, total=numupdates,
>>> unit=_files)
>>>               fl, = args
>>>               repo.ui.warn(_("note: possible conflict - %s was renamed "
>>>                              "multiple times to:\n") % f)
>>>               for nf in fl:
>>>                   repo.ui.warn(" %s\n" % nf)
>>> -        elif m == "rd": # rename and delete
>>> +
>>> +        # rename and delete
>>> +        elif m == "rd":
>>> +            repo.ui.debug(" %s: %s -> rd\n" % (f, msg))
>>> +            z += 1
>>> +            progress(_updating, z, item=f, total=numupdates,
>>> unit=_files)
>>>               fl, = args
>>>               repo.ui.warn(_("note: possible conflict - %s was deleted "
>>>                              "and renamed to:\n") % f)
>>>               for nf in fl:
>>>                   repo.ui.warn(" %s\n" % nf)
>>> -        elif m == "e": # exec
>>> +
>>> +        # exec
>>> +        elif m == "e":
>>> +            repo.ui.debug(" %s: %s -> e\n" % (f, msg))
>>> +            z += 1
>>> +            progress(_updating, z, item=f, total=numupdates,
>>> unit=_files)
>>>               flags, = args
>>>               audit(f)
>>>               util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
>>>               updated += 1
>>> +
>>>       ms.commit()
>>>       progress(_updating, None, total=numupdates, unit=_files)
>>>
>>> @@ -744,7 +789,7 @@ def calculateupdates(repo, wctx, mctx, a
>>>               actions = manifestmerge(repo, wctx, mctx, ancestor,
>>>                                       branchmerge, force,
>>>                                       partial, acceptremote,
>>> followcopies)
>>> -            for a in sorted(actions):
>>> +            for a in sorted(actions, key=lambda a: (a[1], a)):
>>
>> New obscure key added to the sorted call?
>
> It is only temporary so the convoluted code gives the same output as the
> simplified code will do in step 8.

Code comment + changeset description.

Looks like there was much to said in this commit message. At least to 
explain the reviewer what was going on.

Patch

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -571,9 +571,9 @@  def getremove(repo, mctx, overwrite, arg
     wwrite = repo.wwrite
     audit = repo.wopener.audit
     i = 0
-    for arg in args:
-        f = arg[0]
-        if arg[1] == 'r':
+    for f, m, args, msg in args:
+        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
+        if m == 'r':
             if verbose:
                 repo.ui.note(_("removing %s\n") % f)
             audit(f)
@@ -585,7 +585,7 @@  def getremove(repo, mctx, overwrite, arg
         else:
             if verbose:
                 repo.ui.note(_("getting %s\n") % f)
-            wwrite(f, fctx(f).data(), arg[2][0])
+            wwrite(f, fctx(f).data(), args[0])
         if i == 100:
             yield i, f
             i = 0
@@ -612,12 +612,11 @@  def applyupdates(repo, actions, wctx, mc
     # prescan for merges
     for a in actions:
         f, m, args, msg = a
-        repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
         if m == "m": # merge
             f1, f2, fa, move, anc = args
             if f == '.hgsubstate': # merged internally
                 continue
-            repo.ui.debug("  preserving %s for resolve of %s\n" % (f1, f))
+            repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
             fcl = wctx[f1]
             fco = mctx[f2]
             actx = repo[anc]
@@ -647,7 +646,7 @@  def applyupdates(repo, actions, wctx, mc
     updated = len(updateactions)
     removeactions = [a for a in workeractions if a[1] == 'r']
     removed = len(removeactions)
-    actions = [a for a in actions if a[1] not in 'grk']
+    actions = [a for a in actions if a[1] not in 'gr']
 
     hgsub = [a[1] for a in workeractions if a[0] == '.hgsubstate']
     if hgsub and hgsub[0] == 'r':
@@ -671,10 +670,30 @@  def applyupdates(repo, actions, wctx, mc
     if hgsub and hgsub[0] == 'g':
         subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
 
-    for i, a in enumerate(actions):
-        f, m, args, msg = a
-        progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files)
-        if m == "m": # merge
+    for f, m, args, msg in actions:
+
+        # forget (manifest only, just log it) (must come first)
+        if m == "f":
+            repo.ui.debug(" %s: %s -> f\n" % (f, msg))
+            z += 1
+            progress(_updating, z, item=f, total=numupdates, unit=_files)
+
+        # re-add (manifest only, just log it)
+        elif m == "a":
+            repo.ui.debug(" %s: %s -> a\n" % (f, msg))
+            z += 1
+            progress(_updating, z, item=f, total=numupdates, unit=_files)
+
+        # keep (noop, just log it)
+        elif m == "k":
+            repo.ui.debug(" %s: %s -> k\n" % (f, msg))
+            # no progress
+
+        # merge
+        elif m == "m":
+            repo.ui.debug(" %s: %s -> m\n" % (f, msg))
+            z += 1
+            progress(_updating, z, item=f, total=numupdates, unit=_files)
             f1, f2, fa, move, anc = args
             if f == '.hgsubstate': # subrepo states need updating
                 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
@@ -689,35 +708,61 @@  def applyupdates(repo, actions, wctx, mc
                     updated += 1
                 else:
                     merged += 1
-        elif m == "dm": # directory rename, move local
+
+        # directory rename, move local
+        elif m == "dm":
+            repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
+            z += 1
+            progress(_updating, z, item=f, total=numupdates, unit=_files)
             f0, flags = args
             repo.ui.note(_("moving %s to %s\n") % (f0, f))
             audit(f)
             repo.wwrite(f, wctx.filectx(f0).data(), flags)
             util.unlinkpath(repo.wjoin(f0))
             updated += 1
-        elif m == "dg": # local directory rename, get
+
+        # local directory rename, get
+        elif m == "dg":
+            repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
+            z += 1
+            progress(_updating, z, item=f, total=numupdates, unit=_files)
             f0, flags = args
             repo.ui.note(_("getting %s to %s\n") % (f0, f))
             repo.wwrite(f, mctx.filectx(f0).data(), flags)
             updated += 1
-        elif m == "dr": # divergent renames
+
+        # divergent renames
+        elif m == "dr":
+            repo.ui.debug(" %s: %s -> dr\n" % (f, msg))
+            z += 1
+            progress(_updating, z, item=f, total=numupdates, unit=_files)
             fl, = args
             repo.ui.warn(_("note: possible conflict - %s was renamed "
                            "multiple times to:\n") % f)
             for nf in fl:
                 repo.ui.warn(" %s\n" % nf)
-        elif m == "rd": # rename and delete
+
+        # rename and delete
+        elif m == "rd":
+            repo.ui.debug(" %s: %s -> rd\n" % (f, msg))
+            z += 1
+            progress(_updating, z, item=f, total=numupdates, unit=_files)
             fl, = args
             repo.ui.warn(_("note: possible conflict - %s was deleted "
                            "and renamed to:\n") % f)
             for nf in fl:
                 repo.ui.warn(" %s\n" % nf)
-        elif m == "e": # exec
+
+        # exec
+        elif m == "e":
+            repo.ui.debug(" %s: %s -> e\n" % (f, msg))
+            z += 1
+            progress(_updating, z, item=f, total=numupdates, unit=_files)
             flags, = args
             audit(f)
             util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
             updated += 1
+
     ms.commit()
     progress(_updating, None, total=numupdates, unit=_files)
 
@@ -744,7 +789,7 @@  def calculateupdates(repo, wctx, mctx, a
             actions = manifestmerge(repo, wctx, mctx, ancestor,
                                     branchmerge, force,
                                     partial, acceptremote, followcopies)
-            for a in sorted(actions):
+            for a in sorted(actions, key=lambda a: (a[1], a)):
                 f, m, args, msg = a
                 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
                 if f in fbids:
@@ -829,28 +874,41 @@  def calculateupdates(repo, wctx, mctx, a
 def recordupdates(repo, actions, branchmerge):
     "record merge actions to the dirstate"
 
-    for a in actions:
-        f, m, args, msg = a
-        if m == "r": # remove (must come first)
+    for f, m, args, msg in actions:
+
+        # remove (must come first)
+        if m == "r": # remove
             if branchmerge:
                 repo.dirstate.remove(f)
             else:
                 repo.dirstate.drop(f)
-        elif m == "f": # forget (must come first)
+
+        # forget (must come first)
+        elif m == "f":
             repo.dirstate.drop(f)
-        elif m == "a": # re-add
+
+        # re-add
+        elif m == "a":
             if not branchmerge:
                 repo.dirstate.add(f)
-        elif m == "e": # exec change
+
+        # exec change
+        elif m == "e":
             repo.dirstate.normallookup(f)
-        elif m == "k": # keep
+
+        # keep
+        elif m == "k":
             pass
-        elif m == "g": # get
+
+        # get
+        elif m == "g":
             if branchmerge:
                 repo.dirstate.otherparent(f)
             else:
                 repo.dirstate.normal(f)
-        elif m == "m": # merge
+
+        # merge
+        elif m == "m":
             f1, f2, fa, move, anc = args
             if branchmerge:
                 # We've done a branch merge, mark this file as merged
@@ -873,7 +931,9 @@  def recordupdates(repo, actions, branchm
                     repo.dirstate.normallookup(f)
                 if move:
                     repo.dirstate.drop(f1)
-        elif m == "dm": # directory rename, move local
+
+        # directory rename, move local
+        elif m == "dm":
             f0, flag = args
             if f0 not in repo.dirstate:
                 # untracked file moved
@@ -885,7 +945,9 @@  def recordupdates(repo, actions, branchm
             else:
                 repo.dirstate.normal(f)
                 repo.dirstate.drop(f0)
-        elif m == "dg": # directory rename, get
+
+        # directory rename, get
+        elif m == "dg":
             f0, flag = args
             if branchmerge:
                 repo.dirstate.add(f)
diff --git a/tests/test-copy-move-merge.t b/tests/test-copy-move-merge.t
--- a/tests/test-copy-move-merge.t
+++ b/tests/test-copy-move-merge.t
@@ -31,16 +31,16 @@ 
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: b8bf91eeebbc, local: add3f11052fa+, remote: 17c05bb7fcb6
+   preserving a for resolve of b
+   preserving a for resolve of c
+  removing a
    b: remote moved from a -> m
-    preserving a for resolve of b
-   c: remote moved from a -> m
-    preserving a for resolve of c
-  removing a
   updating: b 1/2 files (50.00%)
   picked tool 'internal:merge' for b (binary False symlink False)
   merging a and b to b
   my b@add3f11052fa+ other b@17c05bb7fcb6 ancestor a@b8bf91eeebbc
    premerge successful
+   c: remote moved from a -> m
   updating: c 2/2 files (100.00%)
   picked tool 'internal:merge' for c (binary False symlink False)
   merging a and c to c
diff --git a/tests/test-double-merge.t b/tests/test-double-merge.t
--- a/tests/test-double-merge.t
+++ b/tests/test-double-merge.t
@@ -35,15 +35,15 @@  we get conflicts that shouldn't be there
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: e6dc8efe11cc, local: 6a0df1dad128+, remote: 484bf6903104
+   preserving foo for resolve of bar
+   preserving foo for resolve of foo
    bar: remote copied from foo -> m
-    preserving foo for resolve of bar
-   foo: versions differ -> m
-    preserving foo for resolve of foo
   updating: bar 1/2 files (50.00%)
   picked tool 'internal:merge' for bar (binary False symlink False)
   merging foo and bar to bar
   my bar@6a0df1dad128+ other bar@484bf6903104 ancestor foo@e6dc8efe11cc
    premerge successful
+   foo: versions differ -> m
   updating: foo 2/2 files (100.00%)
   picked tool 'internal:merge' for foo (binary False symlink False)
   merging foo
diff --git a/tests/test-graft.t b/tests/test-graft.t
--- a/tests/test-graft.t
+++ b/tests/test-graft.t
@@ -137,8 +137,8 @@  Graft out of order, skipping a merge and
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
+   preserving b for resolve of b
    b: local copied/moved from a -> m
-    preserving b for resolve of b
   updating: b 1/1 files (100.00%)
   picked tool 'internal:merge' for b (binary False symlink False)
   merging b and a to b
@@ -151,21 +151,21 @@  Graft out of order, skipping a merge and
    branchmerge: True, force: True, partial: False
    ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
    e: remote is newer -> g
-   b: keep -> k
   getting e
   updating: e 1/1 files (100.00%)
+   b: keep -> k
   e
   grafting revision 4
     searching for copies back to rev 1
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
+   preserving e for resolve of e
    d: remote is newer -> g
+  getting d
+  updating: d 1/2 files (50.00%)
    b: keep -> k
    e: versions differ -> m
-    preserving e for resolve of e
-  getting d
-  updating: d 1/2 files (50.00%)
   updating: e 2/2 files (100.00%)
   picked tool 'internal:merge' for e (binary False symlink False)
   merging e
diff --git a/tests/test-issue672.t b/tests/test-issue672.t
--- a/tests/test-issue672.t
+++ b/tests/test-issue672.t
@@ -35,12 +35,12 @@  http://mercurial.selenic.com/bts/issue67
    branchmerge: True, force: False, partial: False
    ancestor: 81f4b099af3d, local: c64f439569a9+, remote: c12dcd37c90a
    1: other deleted -> r
-   1a: remote created -> g
-   2: keep -> k
   removing 1
   updating: 1 1/2 files (50.00%)
+   1a: remote created -> g
   getting 1a
   updating: 1a 2/2 files (100.00%)
+   2: keep -> k
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
 
@@ -66,8 +66,8 @@  http://mercurial.selenic.com/bts/issue67
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: c64f439569a9, local: e327dca35ac8+, remote: 746e9549ea96
+   preserving 1a for resolve of 1a
    1a: local copied/moved from 1 -> m
-    preserving 1a for resolve of 1a
   updating: 1a 1/1 files (100.00%)
   picked tool 'internal:merge' for 1a (binary False symlink False)
   merging 1a and 1 to 1a
@@ -89,9 +89,9 @@  http://mercurial.selenic.com/bts/issue67
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: c64f439569a9, local: 746e9549ea96+, remote: e327dca35ac8
+   preserving 1 for resolve of 1a
+  removing 1
    1a: remote moved from 1 -> m
-    preserving 1 for resolve of 1a
-  removing 1
   updating: 1a 1/1 files (100.00%)
   picked tool 'internal:merge' for 1a (binary False symlink False)
   merging 1 and 1a to 1a
diff --git a/tests/test-merge-commit.t b/tests/test-merge-commit.t
--- a/tests/test-merge-commit.t
+++ b/tests/test-merge-commit.t
@@ -71,8 +71,8 @@  This should use bar@rev2 as the ancestor
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 0555950ead28
+   preserving bar for resolve of bar
    bar: versions differ -> m
-    preserving bar for resolve of bar
   updating: bar 1/1 files (100.00%)
   picked tool 'internal:merge' for bar (binary False symlink False)
   merging bar
@@ -158,8 +158,8 @@  This should use bar@rev2 as the ancestor
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 3ffa6b9e35f0
+   preserving bar for resolve of bar
    bar: versions differ -> m
-    preserving bar for resolve of bar
   updating: bar 1/1 files (100.00%)
   picked tool 'internal:merge' for bar (binary False symlink False)
   merging bar
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -81,11 +81,11 @@  Criss cross merging
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 0f6b37dbe527, local: 3b08d01b0ab5+, remote: adfe50279922
+   preserving f2 for resolve of f2
    f1: remote is newer -> g
-   f2: versions differ -> m
-    preserving f2 for resolve of f2
   getting f1
   updating: f1 1/2 files (50.00%)
+   f2: versions differ -> m
   updating: f2 2/2 files (100.00%)
   picked tool 'internal:dump' for f2 (binary False symlink False)
   merging f2
@@ -143,8 +143,8 @@  Redo merge with merge.preferancestor="*"
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
+   f2: keep -> k
    f1: versions differ -> m
-   f2: keep -> k
   
   auction for merging merge bids
    f1: picking 'get' action
@@ -152,9 +152,9 @@  Redo merge with merge.preferancestor="*"
   end of auction
   
    f1: remote is newer -> g
-   f2: keep -> k
   getting f1
   updating: f1 1/1 files (100.00%)
+   f2: keep -> k
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
 
@@ -188,8 +188,8 @@  The other way around:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 40663881a6dd, local: adfe50279922+, remote: 3b08d01b0ab5
+   f2: remote is newer -> g
    f1: versions differ -> m
-   f2: remote is newer -> g
   
   auction for merging merge bids
    f1: picking 'keep' action
@@ -197,9 +197,9 @@  The other way around:
   end of auction
   
    f2: remote is newer -> g
-   f1: keep -> k
   getting f2
   updating: f2 1/1 files (100.00%)
+   f1: keep -> k
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
 
@@ -254,8 +254,8 @@  Verify how the output looks and and how 
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 40663881a6dd, local: 3b08d01b0ab5+, remote: adfe50279922
+   f2: keep -> k
    f1: versions differ -> m
-   f2: keep -> k
   
   auction for merging merge bids
    f1: picking 'get' action
@@ -263,9 +263,9 @@  Verify how the output looks and and how 
   end of auction
   
    f1: remote is newer -> g
-   f2: keep -> k
   getting f1
   updating: f1 1/1 files (100.00%)
+   f2: keep -> k
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
 
diff --git a/tests/test-merge-types.t b/tests/test-merge-types.t
--- a/tests/test-merge-types.t
+++ b/tests/test-merge-types.t
@@ -34,8 +34,8 @@  Symlink is local parent, executable is o
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c
+   preserving a for resolve of a
    a: versions differ -> m
-    preserving a for resolve of a
   updating: a 1/1 files (100.00%)
   picked tool 'internal:merge' for a (binary False symlink True)
   merging a
@@ -67,8 +67,8 @@  Symlink is other parent, executable is l
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
+   preserving a for resolve of a
    a: versions differ -> m
-    preserving a for resolve of a
   updating: a 1/1 files (100.00%)
   picked tool 'internal:merge' for a (binary False symlink True)
   merging a
@@ -101,8 +101,8 @@  Update to link with local change should 
   resolving manifests
    branchmerge: False, force: False, partial: False
    ancestor: c334dc3be0da, local: c334dc3be0da+, remote: 521a1e40188f
+   preserving a for resolve of a
    a: versions differ -> m
-    preserving a for resolve of a
   updating: a 1/1 files (100.00%)
   (couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
   picked tool 'internal:prompt' for a (binary False symlink True)
diff --git a/tests/test-merge7.t b/tests/test-merge7.t
--- a/tests/test-merge7.t
+++ b/tests/test-merge7.t
@@ -83,8 +83,8 @@  pull and merge from test-a again
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 96b70246a118, local: 50c3a7e29886+, remote: 40d11a4173a8
+   preserving test.txt for resolve of test.txt
    test.txt: versions differ -> m
-    preserving test.txt for resolve of test.txt
   updating: test.txt 1/1 files (100.00%)
   picked tool 'internal:merge' for test.txt (binary False symlink False)
   merging test.txt
diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t
--- a/tests/test-rebase-conflicts.t
+++ b/tests/test-rebase-conflicts.t
@@ -219,9 +219,9 @@  Check that the right ancestors is used w
    branchmerge: False, force: True, partial: False
    ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
    f2.txt: other deleted -> r
-   f1.txt: remote created -> g
   removing f2.txt
   updating: f2.txt 1/2 files (50.00%)
+   f1.txt: remote created -> g
   getting f1.txt
   updating: f1.txt 2/2 files (100.00%)
    merge against 9:e31216eec445
@@ -254,9 +254,9 @@  Check that the right ancestors is used w
    branchmerge: False, force: False, partial: False
    ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
    f1.txt: other deleted -> r
-   f2.txt: remote created -> g
   removing f1.txt
   updating: f1.txt 1/2 files (50.00%)
+   f2.txt: remote created -> g
   getting f2.txt
   updating: f2.txt 2/2 files (100.00%)
   3 changesets found
diff --git a/tests/test-rename-dir-merge.t b/tests/test-rename-dir-merge.t
--- a/tests/test-rename-dir-merge.t
+++ b/tests/test-rename-dir-merge.t
@@ -40,16 +40,16 @@ 
    branchmerge: True, force: False, partial: False
    ancestor: f9b20c0d4c51, local: ce36d17b18fb+, remote: 397f8b00a740
    a/a: other deleted -> r
+  removing a/a
    a/b: other deleted -> r
-   b/a: remote created -> g
-   b/b: remote created -> g
-   b/c: remote directory rename - move from a/c -> dm
-  removing a/a
   removing a/b
   updating: a/b 2/5 files (40.00%)
+   b/a: remote created -> g
   getting b/a
+   b/b: remote created -> g
   getting b/b
   updating: b/b 4/5 files (80.00%)
+   b/c: remote directory rename - move from a/c -> dm
   updating: b/c 5/5 files (100.00%)
   moving a/c to b/c (glob)
   3 files updated, 0 files merged, 2 files removed, 0 files unresolved
diff --git a/tests/test-rename-merge1.t b/tests/test-rename-merge1.t
--- a/tests/test-rename-merge1.t
+++ b/tests/test-rename-merge1.t
@@ -36,18 +36,18 @@ 
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
+   preserving a for resolve of b
+  removing a
    b2: remote created -> g
-   b: remote moved from a -> m
-    preserving a for resolve of b
-   a2: divergent renames -> dr
-  removing a
   getting b2
   updating: b2 1/3 files (33.33%)
+   b: remote moved from a -> m
   updating: b 2/3 files (66.67%)
   picked tool 'internal:merge' for b (binary False symlink False)
   merging a and b to b
   my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
    premerge successful
+   a2: divergent renames -> dr
   updating: a2 3/3 files (100.00%)
   note: possible conflict - a2 was renamed multiple times to:
    c2
@@ -182,9 +182,9 @@  Check for issue3074
    branchmerge: True, force: False, partial: False
    ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
    newfile: remote created -> g
-   file: rename and delete -> rd
   getting newfile
   updating: newfile 1/2 files (50.00%)
+   file: rename and delete -> rd
   updating: file 2/2 files (100.00%)
   note: possible conflict - file was deleted and renamed to:
    newfile
diff --git a/tests/test-rename-merge2.t b/tests/test-rename-merge2.t
--- a/tests/test-rename-merge2.t
+++ b/tests/test-rename-merge2.t
@@ -86,16 +86,16 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
+   preserving a for resolve of b
+   preserving rev for resolve of rev
    a: keep -> k
    b: remote copied from a -> m
-    preserving a for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging a and b to b
   my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
    premerge successful
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -122,18 +122,18 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    a: remote is newer -> g
-   b: local copied/moved from a -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   getting a
   updating: a 1/3 files (33.33%)
+   b: local copied/moved from a -> m
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b and a to b
   my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
    premerge successful
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -160,16 +160,16 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
+   preserving a for resolve of b
+   preserving rev for resolve of rev
+  removing a
    b: remote moved from a -> m
-    preserving a for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
-  removing a
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging a and b to b
   my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
    premerge successful
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -195,15 +195,15 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    b: local copied/moved from a -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b and a to b
   my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
    premerge successful
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -229,11 +229,11 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
+   preserving rev for resolve of rev
    b: remote created -> g
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   getting b
   updating: b 1/2 files (50.00%)
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -259,8 +259,8 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
+   preserving rev for resolve of rev
    rev: versions differ -> m
-    preserving rev for resolve of rev
   updating: rev 1/1 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -286,14 +286,14 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
+   preserving rev for resolve of rev
    a: other deleted -> r
-   b: remote created -> g
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   removing a
   updating: a 1/3 files (33.33%)
+   b: remote created -> g
   getting b
   updating: b 2/3 files (66.67%)
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -318,8 +318,8 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
+   preserving rev for resolve of rev
    rev: versions differ -> m
-    preserving rev for resolve of rev
   updating: rev 1/1 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -341,14 +341,14 @@  args:
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -379,16 +379,16 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
+   preserving rev for resolve of rev
    c: remote created -> g
-   rev: versions differ -> m
-    preserving rev for resolve of rev
-   a: divergent renames -> dr
   getting c
   updating: c 1/3 files (33.33%)
+   rev: versions differ -> m
   updating: rev 2/3 files (66.67%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
   my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
+   a: divergent renames -> dr
   updating: a 3/3 files (100.00%)
   note: possible conflict - a was renamed multiple times to:
    b
@@ -411,14 +411,14 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -441,17 +441,17 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    a: other deleted -> r
-   b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   removing a
   updating: a 1/3 files (33.33%)
+   b: versions differ -> m
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -473,17 +473,17 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    a: remote is newer -> g
-   b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   getting a
   updating: a 1/3 files (33.33%)
+   b: versions differ -> m
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -506,17 +506,17 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    a: other deleted -> r
-   b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   removing a
   updating: a 1/3 files (33.33%)
+   b: versions differ -> m
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -538,17 +538,17 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    a: remote is newer -> g
-   b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   getting a
   updating: a 1/3 files (33.33%)
+   b: versions differ -> m
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -571,15 +571,15 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    a: keep -> k
    b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -604,17 +604,17 @@  m "um a c" "um x c" "      " "10 do merg
    ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
   remote changed a which local deleted
   use (c)hanged version or leave (d)eleted? c
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    a: prompt recreating -> g
-   b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   getting a
   updating: a 1/3 files (33.33%)
+   b: versions differ -> m
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -639,16 +639,16 @@  m "um a c" "um x c" "      " "10 do merg
    ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
   local changed a which remote deleted
   use (c)hanged version or (d)elete? c
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    a: prompt keep -> a
+  updating: a 1/3 files (33.33%)
    b: versions differ -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
-  updating: a 1/3 files (33.33%)
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
   my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -674,15 +674,15 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
+   preserving a for resolve of b
+   preserving rev for resolve of rev
+  removing a
    b: remote moved from a -> m
-    preserving a for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
-  removing a
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging a and b to b
   my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -708,14 +708,14 @@  m "um a c" "um x c" "      " "10 do merg
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    b: local copied/moved from a -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b and a to b
   my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
+   rev: versions differ -> m
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -746,18 +746,18 @@  m "nm a b" "um x a" "      " "22 get a, 
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
+   preserving b for resolve of b
+   preserving rev for resolve of rev
    c: remote created -> g
-   b: local copied/moved from a -> m
-    preserving b for resolve of b
-   rev: versions differ -> m
-    preserving rev for resolve of rev
   getting c
   updating: c 1/3 files (33.33%)
+   b: local copied/moved from a -> m
   updating: b 2/3 files (66.67%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b and a to b
   my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
    premerge successful
+   rev: versions differ -> m
   updating: rev 3/3 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev
@@ -836,28 +836,18 @@  8  f  (f)  f   f   "remote differs from 
    ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
   remote changed 8/f which local deleted
   use (c)hanged version or leave (d)eleted? c
+   preserving 0/f for resolve of 0/f
+   preserving 1/g for resolve of 1/g
+   preserving 2/f for resolve of 2/f
+   preserving 3/f for resolve of 3/f
+   preserving 3/f for resolve of 3/g
+   preserving 4/f for resolve of 4/g
+   preserving 5/f for resolve of 5/f
+   preserving 5/g for resolve of 5/g
+   preserving 6/g for resolve of 6/g
+   preserving 7/f for resolve of 7/f
+  removing 4/f
    8/f: prompt recreating -> g
-   0/f: versions differ -> m
-    preserving 0/f for resolve of 0/f
-   1/g: versions differ -> m
-    preserving 1/g for resolve of 1/g
-   2/f: versions differ -> m
-    preserving 2/f for resolve of 2/f
-   3/f: versions differ -> m
-    preserving 3/f for resolve of 3/f
-   3/g: remote copied from 3/f -> m
-    preserving 3/f for resolve of 3/g
-   4/g: remote moved from 4/f -> m
-    preserving 4/f for resolve of 4/g
-   5/f: versions differ -> m
-    preserving 5/f for resolve of 5/f
-   5/g: local copied/moved from 5/f -> m
-    preserving 5/g for resolve of 5/g
-   6/g: local copied/moved from 6/f -> m
-    preserving 6/g for resolve of 6/g
-   7/f: remote differs from untracked local -> m
-    preserving 7/f for resolve of 7/f
-  removing 4/f
   getting 8/f
   $ hg mani
   0/f
diff --git a/tests/test-subrepo.t b/tests/test-subrepo.t
--- a/tests/test-subrepo.t
+++ b/tests/test-subrepo.t
@@ -281,8 +281,8 @@  merge tests
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
+   preserving t for resolve of t
    t: versions differ -> m
-    preserving t for resolve of t
   updating: t 1/1 files (100.00%)
   picked tool 'internal:merge' for t (binary False symlink False)
   merging t
diff --git a/tests/test-up-local-change.t b/tests/test-up-local-change.t
--- a/tests/test-up-local-change.t
+++ b/tests/test-up-local-change.t
@@ -46,11 +46,11 @@ 
   resolving manifests
    branchmerge: False, force: False, partial: False
    ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
+   preserving a for resolve of a
    b: remote created -> g
-   a: versions differ -> m
-    preserving a for resolve of a
   getting b
   updating: b 1/2 files (50.00%)
+   a: versions differ -> m
   updating: a 2/2 files (100.00%)
   picked tool 'true' for a (binary False symlink False)
   merging a
@@ -67,11 +67,11 @@ 
   resolving manifests
    branchmerge: False, force: False, partial: False
    ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
+   preserving a for resolve of a
    b: other deleted -> r
-   a: versions differ -> m
-    preserving a for resolve of a
   removing b
   updating: b 1/2 files (50.00%)
+   a: versions differ -> m
   updating: a 2/2 files (100.00%)
   picked tool 'true' for a (binary False symlink False)
   merging a
@@ -100,11 +100,11 @@ 
   resolving manifests
    branchmerge: False, force: False, partial: False
    ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
+   preserving a for resolve of a
    b: remote created -> g
-   a: versions differ -> m
-    preserving a for resolve of a
   getting b
   updating: b 1/2 files (50.00%)
+   a: versions differ -> m
   updating: a 2/2 files (100.00%)
   picked tool 'true' for a (binary False symlink False)
   merging a
@@ -181,14 +181,14 @@  create a second head
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: c19d34741b0a, local: 1e71731e6fbb+, remote: 83c51d0caff4
+   preserving a for resolve of a
+   preserving b for resolve of b
    a: versions differ -> m
-    preserving a for resolve of a
-   b: versions differ -> m
-    preserving b for resolve of b
   updating: a 1/2 files (50.00%)
   picked tool 'true' for a (binary False symlink False)
   merging a
   my a@1e71731e6fbb+ other a@83c51d0caff4 ancestor a@c19d34741b0a
+   b: versions differ -> m
   updating: b 2/2 files (100.00%)
   picked tool 'true' for b (binary False symlink False)
   merging b
diff --git a/tests/test-update-reverse.t b/tests/test-update-reverse.t
--- a/tests/test-update-reverse.t
+++ b/tests/test-update-reverse.t
@@ -69,11 +69,11 @@ 
    branchmerge: False, force: True, partial: False
    ancestor: 91ebc10ed028+, local: 91ebc10ed028+, remote: 71a760306caf
    side1: other deleted -> r
+  removing side1
    side2: other deleted -> r
-   main: remote created -> g
-  removing side1
   removing side2
   updating: side2 2/3 files (66.67%)
+   main: remote created -> g
   getting main
   updating: main 3/3 files (100.00%)
   1 files updated, 0 files merged, 2 files removed, 0 files unresolved