[PATCH] repoview: introduce a `experimental.extra-filter-revs` config

Gregory Szorc gregory.szorc at gmail.com
Wed Apr 17 07:22:31 EDT 2019


On Tue, Apr 16, 2019 at 4:54 PM Pierre-Yves David <
pierre-yves.david at ens-lyon.org> wrote:

> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david at octobus.net>
> # Date 1554565579 -7200
> #      Sat Apr 06 17:46:19 2019 +0200
> # Node ID 86eac5d2d7a1386dca5970126506d07201058200
> # Parent  eebf78724d94649de84f921ff5bd39cbc0f48cb6
> # EXP-Topic repoview
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r
> 86eac5d2d7a1
> repoview: introduce a `experimental.extra-filter-revs` config
>
> The option define revisions to additionally filter out of all repository
> "view".
> The end goal is to provide and easy to way to serve multiple subset of the
> same
> repository using multiple "shares".
>
> The simplest use case of this feature is to have one view serving the
> public
> changesets and one view also serving the draft. This is currently
> achievable
> using the new `server.view` option introduced recently by Joerg
> Sonnenberger.
> However, more advanced use cases need more advanced definitions. For
> example
> some needs a view dedicated to some release branches, or view that hides
> security fixes to be released. Joerg Sonnenberger and I discussed this
> topic at
> the recent mini-sprint and the both of us have seen real life use cases for
> this. (This series got written during the same mini-sprint).
>
> The feature is fully functional, and use similar cache-fallback mechanism
> to
> ensure decent performance. However,there remaining room to ensure each
> share
> caches and hooks collaborate with each others. This will come at a later
> time
> once users start to actually test this feature on real usecase.
>
> diff --git a/mercurial/configitems.py b/mercurial/configitems.py
> --- a/mercurial/configitems.py
> +++ b/mercurial/configitems.py
> @@ -529,6 +529,13 @@ coreconfigitem('experimental', 'evolutio
>  coreconfigitem('experimental', 'evolution.track-operation',
>      default=True,
>  )
> +# repo-level config to exclude a revset visibility
> +#
> +# The target use case is to use `share` to expose different subset of the
> same
> +# repository, especially server side. See also `server.view`.
> +coreconfigitem('experimental', 'extra-filter-revs',
> +    default=None,
> +)
>  coreconfigitem('experimental', 'maxdeltachainspan',
>      default=-1,
>  )
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -1050,6 +1050,8 @@ class localrepository(object):
>          # Signature to cached matcher instance.
>          self._sparsematchercache = {}
>
> +        self._extrafilterid = repoview.extrafilter(ui)
> +
>      def _getvfsward(self, origfunc):
>          """build a ward for self.vfs"""
>          rref = weakref.ref(self)
> @@ -1197,6 +1199,9 @@ class localrepository(object):
>
>          In other word, there is always only one level of `repoview`
> "filtering".
>          """
> +        if self._extrafilterid is not None:
> +            name = name + '%'  + self._extrafilterid
> +
>          cls = repoview.newtype(self.unfiltered().__class__)
>          return cls(self, name, visibilityexceptions)
>
> diff --git a/mercurial/repoview.py b/mercurial/repoview.py
> --- a/mercurial/repoview.py
> +++ b/mercurial/repoview.py
> @@ -17,6 +17,10 @@ from . import (
>      phases,
>      pycompat,
>      tags as tagsmod,
> +    util,
> +)
> +from .utils import (
> +    repoviewutil,
>  )
>
>  def hideablerevs(repo):
> @@ -154,6 +158,35 @@ filtertable = {'visible': computehidden,
>                 'immutable':  computemutable,
>                 'base':  computeimpactable}
>
> +_basefiltername = list(filtertable)
> +
> +def extrafilter(ui):
> +    """initialize extra filter and return its id
> +
> +    If extra filtering is configured, we make sure the associated
> filtered view
> +    are declared and return the associated id.
> +    """
> +    frevs = ui.config('experimental', 'extra-filter-revs')
> +    if frevs is None:
> +        return None
> +
> +    fid = util.DIGESTS['sha512'](frevs).hexdigest()
>

Why are we computing a hash here? Why not store the raw query? Is it
because the filter names can be persisted to disk in the cache and must
therefore be valid filenames? Is % an allowed character on all filesystems?
Maybe '-' would be safer?


> +
> +    combine = lambda fname: fname + '%' + fid
> +
> +    subsettable = repoviewutil.subsettable
> +
> +    if combine('base') not in filtertable:
> +        for name in _basefiltername:
> +            def extrafilteredrevs(repo, *args, **kwargs):
> +                baserevs = filtertable[name](repo, *args, **kwargs)
> +                extrarevs = frozenset(repo.revs(frevs))
> +                return baserevs | extrarevs
> +            filtertable[combine(name)] = extrafilteredrevs
> +            if name in subsettable:
> +                subsettable[combine(name)] = combine(subsettable[name])
> +    return fid
> +
>  def filterrevs(repo, filtername, visibilityexceptions=None):
>      """returns set of filtered revision for this filter name
>
> diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py
> --- a/mercurial/statichttprepo.py
> +++ b/mercurial/statichttprepo.py
> @@ -155,6 +155,7 @@ class statichttprepository(localrepo.loc
>
>          self.names = namespaces.namespaces()
>          self.filtername = None
> +        self._extrafilterid = None
>
>          try:
>              requirements = set(self.vfs.read(b'requires').splitlines())
> diff --git a/tests/test-server-view.t b/tests/test-server-view.t
> --- a/tests/test-server-view.t
> +++ b/tests/test-server-view.t
> @@ -34,5 +34,21 @@
>    date:        Thu Jan 01 00:00:00 1970 +0000
>    summary:     r0
>
> +
> +Check same result using `experimental.extra-filter-revs`
> +
> +  $ hg -R test --config experimental.extra-filter-revs='not public()'
> serve -p $HGPORT1 -d --pid-file=hg2.pid -E errors.log
> +  $ cat hg2.pid >> $DAEMON_PIDS
> +  $ hg -R test2 incoming http://foo:xyzzy@localhost:$HGPORT1/
> +  comparing with http://foo:***@localhost:$HGPORT1/
> +  changeset:   0:1ea73414a91b
> +  tag:         tip
> +  user:        debugbuilddag
> +  date:        Thu Jan 01 00:00:00 1970 +0000
> +  summary:     r0
> +
> +
> +cleanup
> +
>    $ cat errors.log
>    $ killdaemons.py
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.mercurial-scm.org/pipermail/mercurial-devel/attachments/20190417/cae23875/attachment.html>


More information about the Mercurial-devel mailing list