[PATCH 2 of 3 V2] context: add a `blockancestors(fctx, fromline, toline)` function

Augie Fackler raf at durin42.com
Sat Dec 24 14:58:59 EST 2016


On Fri, Dec 16, 2016 at 02:30:14PM +0100, Denis Laxalde wrote:
> # HG changeset patch
> # User Denis Laxalde <denis.laxalde at logilab.fr>
> # Date 1480086869 -3600
> #      Fri Nov 25 16:14:29 2016 +0100
> # Node ID c8dfd10c5865cfe882a00595743f3f709f41317f
> # Parent  17eee60ccbafe46f539a75484ebf110377781fb1
> # EXP-Topic linerange-log/revset
> context: add a `blockancestors(fctx, fromline, toline)` function
>
> This yields ancestors of `fctx` by only keeping changesets touching the file
> within specified linerange = (fromline, toline). It only follows first parent,
> since this yields weird results in case of merge (might be improved later).

Should we document the limitations of this code in the revset that
makes it user-facing? If it's giving weird behavior in the presence of
merges I feel like we should documen that so nobody trusts it when
merges are in play...

>
> Matching revisions are found by inspecting the result of `mdiff.allblocks()`,
> filtered by `mdiff.blocksinrange()`, to find out if there are blocks of type
> "!" within specified line range.
>
> diff --git a/mercurial/context.py b/mercurial/context.py
> --- a/mercurial/context.py
> +++ b/mercurial/context.py
> @@ -1153,6 +1153,29 @@ class filectx(basefilectx):
>          return [filectx(self._repo, self._path, fileid=x,
>                          filelog=self._filelog) for x in c]
>
> +def blockancestors(fctx, fromline, toline):
> +    """Yield ancestors of `fctx` with respect to the block of lines within
> +    `fromline`-`toline` range.
> +    """
> +    def changesrange(fctx1, fctx2, linerange2):
> +        """Return `(diffinrange, linerange1)` where `diffinrange` is True
> +        if diff from fctx2 to fctx1 has changes in linerange2 and
> +        `linerange1` is the new line range for fctx1.
> +        """
> +        diffopts = patch.diffopts(fctx._repo.ui)
> +        blocks = mdiff.allblocks(fctx1.data(), fctx2.data(), diffopts)
> +        filteredblocks, linerange1 = mdiff.blocksinrange(blocks, linerange2)
> +        diffinrange = any(stype == '!' for _, stype in filteredblocks)
> +        return diffinrange, linerange1
> +
> +    c, linerange2 = fctx, (fromline, toline)
> +    for p in fctx.ancestors(followfirst=True):  # TODO handle followfirst
> +        inrangep, linerange1 = changesrange(p, c, linerange2)
> +        if inrangep:
> +            yield c
> +        c, linerange2 = p, linerange1
> +    yield c
> +
>  class committablectx(basectx):
>      """A committablectx object provides common functionality for a context that
>      wants the ability to commit, e.g. workingctx or memctx."""
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list