[PATCH] histedit: handle obsolete commits unknown to histedit state

Yuya Nishihara yuya at tcha.org
Sun Jan 17 07:44:50 CST 2016


On Thu, 14 Jan 2016 11:19:41 -0800, Kostia Balytskyi wrote:
> # HG changeset patch
> # User Kostia Balytskyi <ikostia at fb.com>
> # Date 1452727707 28800
> #      Wed Jan 13 15:28:27 2016 -0800
> # Node ID 5a36c6cdb955ffb1f8b4c2f26d369b3d331c0492
> # Parent  443848eece189002c542339dc1cf84f49a94c824
> histedit: handle obsolete commits unknown to histedit state
> 
> This fix is intended to solve issue4800. It takes sets of
> final and new commits from histedit's state and replaces
> them with their successor sets.

The logic seems good, but I know little about histedit, so I only checked
coding errors.

> --- a/hgext/histedit.py
> +++ b/hgext/histedit.py
> @@ -1362,6 +1362,27 @@
>      tmpnodes = allsuccs & replaced
>      return newnodes, tmpnodes
>  
> +def nonobsoletesuccessors(repo, nodes):
> +    """find all non-obsolete successors for each of the nodes
> +
> +    This fails if any of the nodes has more than one successor
> +    set, e.g. if it diverged at some point and then became obsolete.
> +    """
> +    result = []
> +    for cl in nodes:
> +        succset = obsolete.successorssets(repo, cl)
> +        if len(succset) > 1:
> +            # successorsset for diverged changeset
> +            # weird situation that should not happen while
> +            # editing history, indicates an error
> +            msg = _("diverged obsolete changeset found " +
> +                    "among nodes in histedit: %s")

_() shouldn't contain expression. '+' isn't necessary because string literals
are concatenated at parsing time.

>      # computed topmost element (necessary for bookmark)
>      if new:
> -        newtopmost = sorted(new, key=state.repo.changelog.rev)[-1]
> +        nonobsoletenew = nonobsoletesuccessors(state.repo, new)
> +        newtopmost = sorted(nonobsoletenew, key=state.repo.changelog.rev)[-1]
>      elif not final:
>          # Nothing rewritten at all. we won't need `newtopmost`
>          # It is the same as `oldtopmost` and `processreplacement` know it
> @@ -1422,7 +1445,7 @@
>          r = state.repo.changelog.rev
>          newtopmost = state.repo[sorted(final, key=r)[0]].p1().node()
>  
> -    return final, tmpnodes, new, newtopmost
> +    return final, tmpnodes, nonobsoletenew, newtopmost

nonobsoletenew isn't initialized if new is empty.


More information about the Mercurial-devel mailing list