[PATCH RFC] hgweb: show explanations for unstable changesets

Yuya Nishihara yuya at tcha.org
Sat Feb 24 07:49:55 EST 2018


On Wed, 21 Feb 2018 21:51:40 +0800, Anton Shestakov wrote:
> # HG changeset patch
> # User Anton Shestakov <av6 at dwimlabs.net>
> # Date 1519199933 -28800
> #      Wed Feb 21 15:58:53 2018 +0800
> # Node ID 628c839d1eec60db3a4548c5bd7430ff4fc9a5a4
> # Parent  aefb75730ea34f545f0756bf8441fc9ae07bf8dc
> hgweb: show explanations for unstable changesets
> 
> This is a port of evolve's feature of listing all unstable changesets in detail
> (`hg evolve --list`).
> 
> A couple things I'd like to bikeshed:
> 
> - "whyunstable": how to call them? These contain all the information needed to
>   explain why certain changesets are unstable, but the best name I've come up
>   with is this or "reasonsunstable"
> 
> - divergentsets() is only used for this feature (even in evolve), but I don't
>   know if it's better to be put into obsutil module instead

(To: Boris) ^^^

> +def divergentsets(repo, ctx):
> +    """Compute sets of commits divergent with a given one"""
> +    cache = {}
> +    base = {}
> +    for n in obsutil.allpredecessors(repo.obsstore, [ctx.node()]):
> +        if n == ctx.node():
> +            # a node can't be a base for divergence with itself
> +            continue
> +        nsuccsets = obsutil.successorssets(repo, n, cache)
> +        for nsuccset in nsuccsets:
> +            if ctx.node() in nsuccset:
> +                # we are only interested in *other* successor sets
> +                continue
> +            if tuple(nsuccset) in base:
> +                # we already know the latest base for this divergency
> +                continue
> +            base[tuple(nsuccset)] = n
> +    return [{'divergentnodes': divset, 'commonpredecessor': b}
> +            for divset, b in base.iteritems()]
> +
> +def whyunstable(repo, ctx):
> +    result = []
> +    if ctx.orphan():
> +        for parent in ctx.parents():
> +            kind = None
> +            if parent.orphan():
> +                kind = 'orphan'
> +            elif parent.obsolete():
> +                kind = 'obsolete'
> +            if kind is not None:
> +                result.append({'instability': 'orphan',
> +                               'reason': '%s parent' % kind,
> +                               'node': parent.hex()})
> +    if ctx.phasedivergent():
> +        predecessors = obsutil.allpredecessors(repo.obsstore, [ctx.node()],
> +                                               ignoreflags=obsolete.bumpedfix)
> +        immutable = [repo[p] for p in predecessors
> +                     if p in repo and not repo[p].mutable()]
> +        for predecessor in immutable:
> +            result.append({'instability': 'phase-divergent',
> +                           'reason': 'immutable predecessor',
> +                           'node': predecessor.hex()})
> +    if ctx.contentdivergent():
> +        dsets = divergentsets(repo, ctx)
> +        for dset in dsets:
> +            divnodes = _siblings(repo[n] for n in dset['divergentnodes'])
> +            result.append({'instability': 'content-divergent',
> +                           'divergentnodes': divnodes,
> +                           'reason': 'predecessor',
> +                           'node': hex(dset['commonpredecessor'])})
> +    return result

Perhaps these functions should be (mostly) moved to obsutil, and preferably
tested without using a web ui.


More information about the Mercurial-devel mailing list