<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>