<div dir="ltr"><div dir="ltr">On Tue, Apr 16, 2019 at 4:54 PM Pierre-Yves David <<a href="mailto:pierre-yves.david@ens-lyon.org">pierre-yves.david@ens-lyon.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># HG changeset patch<br>
# User Pierre-Yves David <<a href="mailto:pierre-yves.david@octobus.net" target="_blank">pierre-yves.david@octobus.net</a>><br>
# Date 1554565579 -7200<br>
#      Sat Apr 06 17:46:19 2019 +0200<br>
# Node ID 86eac5d2d7a1386dca5970126506d07201058200<br>
# Parent  eebf78724d94649de84f921ff5bd39cbc0f48cb6<br>
# EXP-Topic repoview<br>
# Available At <a href="https://bitbucket.org/octobus/mercurial-devel/" rel="noreferrer" target="_blank">https://bitbucket.org/octobus/mercurial-devel/</a><br>
#              hg pull <a href="https://bitbucket.org/octobus/mercurial-devel/" rel="noreferrer" target="_blank">https://bitbucket.org/octobus/mercurial-devel/</a> -r 86eac5d2d7a1<br>
repoview: introduce a `experimental.extra-filter-revs` config<br>
<br>
The option define revisions to additionally filter out of all repository "view".<br>
The end goal is to provide and easy to way to serve multiple subset of the same<br>
repository using multiple "shares".<br>
<br>
The simplest use case of this feature is to have one view serving the public<br>
changesets and one view also serving the draft. This is currently achievable<br>
using the new `server.view` option introduced recently by Joerg Sonnenberger.<br>
However, more advanced use cases need more advanced definitions. For example<br>
some needs a view dedicated to some release branches, or view that hides<br>
security fixes to be released. Joerg Sonnenberger and I discussed this topic at<br>
the recent mini-sprint and the both of us have seen real life use cases for<br>
this. (This series got written during the same mini-sprint).<br>
<br>
The feature is fully functional, and use similar cache-fallback mechanism to<br>
ensure decent performance. However,there remaining room to ensure each share<br>
caches and hooks collaborate with each others. This will come at a later time<br>
once users start to actually test this feature on real usecase.<br>
<br>
diff --git a/mercurial/configitems.py b/mercurial/configitems.py<br>
--- a/mercurial/configitems.py<br>
+++ b/mercurial/configitems.py<br>
@@ -529,6 +529,13 @@ coreconfigitem('experimental', 'evolutio<br>
 coreconfigitem('experimental', 'evolution.track-operation',<br>
     default=True,<br>
 )<br>
+# repo-level config to exclude a revset visibility<br>
+#<br>
+# The target use case is to use `share` to expose different subset of the same<br>
+# repository, especially server side. See also `server.view`.<br>
+coreconfigitem('experimental', 'extra-filter-revs',<br>
+    default=None,<br>
+)<br>
 coreconfigitem('experimental', 'maxdeltachainspan',<br>
     default=-1,<br>
 )<br>
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py<br>
--- a/mercurial/localrepo.py<br>
+++ b/mercurial/localrepo.py<br>
@@ -1050,6 +1050,8 @@ class localrepository(object):<br>
         # Signature to cached matcher instance.<br>
         self._sparsematchercache = {}<br>
<br>
+        self._extrafilterid = repoview.extrafilter(ui)<br>
+<br>
     def _getvfsward(self, origfunc):<br>
         """build a ward for self.vfs"""<br>
         rref = weakref.ref(self)<br>
@@ -1197,6 +1199,9 @@ class localrepository(object):<br>
<br>
         In other word, there is always only one level of `repoview` "filtering".<br>
         """<br>
+        if self._extrafilterid is not None:<br>
+            name = name + '%'  + self._extrafilterid<br>
+<br>
         cls = repoview.newtype(self.unfiltered().__class__)<br>
         return cls(self, name, visibilityexceptions)<br>
<br>
diff --git a/mercurial/repoview.py b/mercurial/repoview.py<br>
--- a/mercurial/repoview.py<br>
+++ b/mercurial/repoview.py<br>
@@ -17,6 +17,10 @@ from . import (<br>
     phases,<br>
     pycompat,<br>
     tags as tagsmod,<br>
+    util,<br>
+)<br>
+from .utils import (<br>
+    repoviewutil,<br>
 )<br>
<br>
 def hideablerevs(repo):<br>
@@ -154,6 +158,35 @@ filtertable = {'visible': computehidden,<br>
                'immutable':  computemutable,<br>
                'base':  computeimpactable}<br>
<br>
+_basefiltername = list(filtertable)<br>
+<br>
+def extrafilter(ui):<br>
+    """initialize extra filter and return its id<br>
+<br>
+    If extra filtering is configured, we make sure the associated filtered view<br>
+    are declared and return the associated id.<br>
+    """<br>
+    frevs = ui.config('experimental', 'extra-filter-revs')<br>
+    if frevs is None:<br>
+        return None<br>
+<br>
+    fid = util.DIGESTS['sha512'](frevs).hexdigest()<br></blockquote><div><br></div><div>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?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+    combine = lambda fname: fname + '%' + fid<br>
+<br>
+    subsettable = repoviewutil.subsettable<br>
+<br>
+    if combine('base') not in filtertable:<br>
+        for name in _basefiltername:<br>
+            def extrafilteredrevs(repo, *args, **kwargs):<br>
+                baserevs = filtertable[name](repo, *args, **kwargs)<br>
+                extrarevs = frozenset(repo.revs(frevs))<br>
+                return baserevs | extrarevs<br>
+            filtertable[combine(name)] = extrafilteredrevs<br>
+            if name in subsettable:<br>
+                subsettable[combine(name)] = combine(subsettable[name])<br>
+    return fid<br>
+<br>
 def filterrevs(repo, filtername, visibilityexceptions=None):<br>
     """returns set of filtered revision for this filter name<br>
<br>
diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py<br>
--- a/mercurial/statichttprepo.py<br>
+++ b/mercurial/statichttprepo.py<br>
@@ -155,6 +155,7 @@ class statichttprepository(localrepo.loc<br>
<br>
         self.names = namespaces.namespaces()<br>
         self.filtername = None<br>
+        self._extrafilterid = None<br>
<br>
         try:<br>
             requirements = set(self.vfs.read(b'requires').splitlines())<br>
diff --git a/tests/test-server-view.t b/tests/test-server-view.t<br>
--- a/tests/test-server-view.t<br>
+++ b/tests/test-server-view.t<br>
@@ -34,5 +34,21 @@<br>
   date:        Thu Jan 01 00:00:00 1970 +0000<br>
   summary:     r0<br>
<br>
+<br>
+Check same result using `experimental.extra-filter-revs`<br>
+<br>
+  $ hg -R test --config experimental.extra-filter-revs='not public()' serve -p $HGPORT1 -d --pid-file=hg2.pid -E errors.log<br>
+  $ cat hg2.pid >> $DAEMON_PIDS<br>
+  $ hg -R test2 incoming http://foo:xyzzy@localhost:$HGPORT1/<br>
+  comparing with http://foo:***@localhost:$HGPORT1/<br>
+  changeset:   0:1ea73414a91b<br>
+  tag:         tip<br>
+  user:        debugbuilddag<br>
+  date:        Thu Jan 01 00:00:00 1970 +0000<br>
+  summary:     r0<br>
+  <br>
+<br>
+cleanup<br>
+<br>
   $ cat errors.log<br>
   $ killdaemons.py<br>
_______________________________________________<br>
Mercurial-devel mailing list<br>
<a href="mailto:Mercurial-devel@mercurial-scm.org" target="_blank">Mercurial-devel@mercurial-scm.org</a><br>
<a href="https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel" rel="noreferrer" target="_blank">https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel</a><br>
</blockquote></div></div>