# HG changeset patch # User Anton Shestakov # Date 1690486783 10800 # Node ID 445240ccb701eed050dc864df967c2eff1d70cd3 # Parent d13cfd9eb6c0b3d5055ce9b90a0fb81aa38c8dd9 topic: add experimental.tns-default-pull-namespaces config option This config option controls what topic namespaces get pulled by default. The current default option is '*', which means all namespaces get pulled. diff -r d13cfd9eb6c0 -r 445240ccb701 hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Wed Aug 30 15:08:35 2023 -0300 +++ b/hgext3rd/topic/__init__.py Thu Jul 27 16:39:43 2023 -0300 @@ -279,6 +279,9 @@ configitem(b'experimental', b'tns-allow-rewrite', default=configitems.dynamicdefault, ) +configitem(b'experimental', b'tns-default-pull-namespaces', + default=configitems.dynamicdefault, +) configitem(b'experimental', b'topic-mode.server', default=configitems.dynamicdefault, ) @@ -624,6 +627,7 @@ else: mode = b'none' caps.add(b'ext-topics-publish=%s' % mode) + caps.add(b'ext-topics-tns-heads') return caps def commit(self, *args, **kwargs): @@ -740,6 +744,19 @@ def branchmaptns(self): usetopic = not self._repo.publishing() return self._repo.branchmaptns(topic=usetopic) + + def tns_heads(self, namespaces): + if b'*' in namespaces: + # pulling all topic namespaces, all changesets are visible + return self._repo.heads() + else: + # only changesets in the selected topic namespaces are visible + h = [] + for branch, nodes in self._repo.branchmaptns().items(): + namedbranch, tns, topic = common.parsefqbn(branch) + if tns == b'none' or tns in namespaces: + h.extend(nodes) + return h peer.__class__ = topicpeer return peer diff -r d13cfd9eb6c0 -r 445240ccb701 hgext3rd/topic/server.py --- a/hgext3rd/topic/server.py Wed Aug 30 15:08:35 2023 -0300 +++ b/hgext3rd/topic/server.py Thu Jul 27 16:39:43 2023 -0300 @@ -2,9 +2,13 @@ # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. +from mercurial.i18n import _ + from mercurial import ( branchmap, + error, extensions, + localrepo, repoview, wireprototypes, wireprotov1peer, @@ -58,6 +62,24 @@ h = repo.heads() return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + b'\n') +def tns_heads(repo, proto, namespaces): + """wireprotocol command to filter heads based on topic namespaces""" + if not common.hastopicext(repo): + return topicheads(repo, proto) + + namespaces = wireprototypes.decodelist(namespaces) + if b'*' in namespaces: + # pulling all topic namespaces, all changesets are visible + h = repo.heads() + else: + # only changesets in the selected topic namespaces are visible + h = [] + for branch, nodes in repo.branchmaptns().items(): + namedbranch, tns, topic = common.parsefqbn(branch) + if tns == b'none' or tns in namespaces: + h.extend(nodes) + return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + b'\n') + def wireprotocaps(orig, repo, proto): """advertise the new topic specific `head` command for client with topic""" caps = orig(repo, proto) @@ -70,6 +92,7 @@ else: mode = b'none' caps.append(b'ext-topics-publish=%s' % mode) + caps.append(b'ext-topics-tns-heads') return caps def setupserver(ui): @@ -77,13 +100,30 @@ wireprotov1server.commands.pop(b'heads') wireprotov1server.wireprotocommand(b'heads', permission=b'pull')(wireprotov1server.heads) wireprotov1server.wireprotocommand(b'_exttopics_heads', permission=b'pull')(topicheads) + wireprotov1server.wireprotocommand(b'tns_heads', b'namespaces', permission=b'pull')(tns_heads) extensions.wrapfunction(wireprotov1server, '_capabilities', wireprotocaps) + class tnspeer(wireprotov1peer.wirepeer): + @wireprotov1peer.batchable + def tns_heads(self, namespaces): + def decode(d): + try: + return wireprototypes.decodelist(d[:-1]) + except ValueError: + self._abort(error.ResponseError(_(b"unexpected response:"), d)) + + return {b'namespaces': wireprototypes.encodelist(namespaces)}, decode + + wireprotov1peer.wirepeer = tnspeer + class topicpeerexecutor(wireprotov1peer.peerexecutor): def callcommand(self, command, args): if command == b'heads': - if self._peer.capable(b'_exttopics_heads'): + if self._peer.capable(b'ext-topics-tns-heads'): + command = b'tns_heads' + args[b'namespaces'] = self._peer.ui.configlist(b'experimental', b'tns-default-pull-namespaces', [b'*']) + elif self._peer.capable(b'_exttopics_heads'): command = b'_exttopics_heads' if getattr(self._peer, '_exttopics_heads', None) is None: self._peer._exttopics_heads = self._peer.heads @@ -92,6 +132,17 @@ wireprotov1peer.peerexecutor = topicpeerexecutor + class topiccommandexecutor(localrepo.localcommandexecutor): + def callcommand(self, command, args): + if command == b'heads': + if self._peer.capable(b'ext-topics-tns-heads'): + command = b'tns_heads' + args[b'namespaces'] = self._peer.ui.configlist(b'experimental', b'tns-default-pull-namespaces', [b'*']) + s = super(topiccommandexecutor, self) + return s.callcommand(command, args) + + localrepo.localcommandexecutor = topiccommandexecutor + if FILTERNAME not in repoview.filtertable: repoview.filtertable[FILTERNAME] = computeunservedtopic # hg <= 4.9 (caebe5e7f4bd) diff -r d13cfd9eb6c0 -r 445240ccb701 tests/test-extension-isolation.t --- a/tests/test-extension-isolation.t Wed Aug 30 15:08:35 2023 -0300 +++ b/tests/test-extension-isolation.t Thu Jul 27 16:39:43 2023 -0300 @@ -133,6 +133,7 @@ $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-topic | egrep 'topics|evoext' _exttopics_heads ext-topics-publish=all + ext-topics-tns-heads topics topics-namespaces $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext' @@ -148,6 +149,7 @@ _evoext_obshashrange_v1 _exttopics_heads ext-topics-publish=all + ext-topics-tns-heads topics topics-namespaces $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext' @@ -156,6 +158,7 @@ $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-topic | egrep 'topics|evoext' _exttopics_heads ext-topics-publish=all + ext-topics-tns-heads topics topics-namespaces $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext' diff -r d13cfd9eb6c0 -r 445240ccb701 tests/test-namespaces-exchange.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-namespaces-exchange.t Thu Jul 27 16:39:43 2023 -0300 @@ -0,0 +1,154 @@ +Limiting topic namespaces during exchange based on a config option + + $ . "$TESTDIR/testlib/common.sh" + + $ cat >> $HGRCPATH << EOF + > [extensions] + > topic = + > [phases] + > publish = no + > [ui] + > ssh = "$PYTHON" "$RUNTESTDIR/dummyssh" + > [devel] + > tns-report-transactions = pull + > EOF + + $ hg init orig + +#testcases local ssh http + +#if http + $ hg serve -R orig -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log + $ cat hg.pid >> $DAEMON_PIDS +#endif + +we advertise the new capability, including during local exchange + +#if local + $ hg debugcapabilities orig | grep topics + ext-topics-publish=none + ext-topics-tns-heads + topics + topics-namespaces +#endif +#if ssh + $ hg debugcapabilities ssh://user@dummy/orig | grep topics + _exttopics_heads + ext-topics-publish=none + ext-topics-tns-heads + topics + topics-namespaces +#endif +#if http + $ hg debugcapabilities http://localhost:$HGPORT/ | grep topics + _exttopics_heads + ext-topics-publish=none + ext-topics-tns-heads + topics + topics-namespaces +#endif + +#if local + $ hg clone orig clone -q +#endif +#if ssh + $ hg clone ssh://user@dummy/orig clone -q +#endif +#if http + $ hg clone http://localhost:$HGPORT/ clone -q +#endif + + $ cd orig + +changesets without topic namespace are freely exchanged + + $ echo apple > a + $ hg debug-topic-namespace --clear + $ hg topic apple + marked working directory as topic: apple + $ hg ci -qAm apple + + $ hg pull -R ../clone + pulling from * (glob) + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + new changesets bf4c1d971543 (1 drafts) + (run 'hg update' to get a working copy) + +changesets with topic namespaces are only exchanged if configuration allows + + $ echo banana > b + $ hg debug-topic-namespace bob + marked working directory as topic namespace: bob + $ hg topic banana + $ hg ci -qAm 'banana' + + $ hg pull -R ../clone --config experimental.tns-default-pull-namespaces=foo + pulling from * (glob) + searching for changes + no changes found + +this config option takes a list of values + + $ hg pull -R ../clone --config experimental.tns-default-pull-namespaces=foo,bob + pulling from * (glob) + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: bob + added 1 changesets with 1 changes to 1 files + new changesets ed9751f04a18 (1 drafts) + (run 'hg update' to get a working copy) + +we have a "permit all" config value + + $ echo coconut > c + $ hg debug-topic-namespace charlie + $ hg topic coconut + $ hg ci -qAm 'coconut' + + $ hg pull -R ../clone --config experimental.tns-default-pull-namespaces=* + pulling from * (glob) + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: charlie + added 1 changesets with 1 changes to 1 files + new changesets 16d2440597e2 (1 drafts) + (run 'hg update' to get a working copy) + +testing the default value for this config option at the moment + + $ echo durian > d + $ hg debug-topic-namespace dave + $ hg topic durian + $ hg ci -qAm 'durian' + + $ hg pull -R ../clone + pulling from * (glob) + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: dave + added 1 changesets with 1 changes to 1 files + new changesets d5d5dda52b2f (1 drafts) + (run 'hg update' to get a working copy) + +#if http + $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS + $ cat $TESTTMP/errors.log +#endif + + $ hg branches + default//dave/durian 3:d5d5dda52b2f + default//charlie/coconut 2:16d2440597e2 (inactive) + default//bob/banana 1:ed9751f04a18 (inactive) + default//apple 0:bf4c1d971543 (inactive) + + $ cd .. diff -r d13cfd9eb6c0 -r 445240ccb701 tests/test-topic-flow-publish-bare.t --- a/tests/test-topic-flow-publish-bare.t Wed Aug 30 15:08:35 2023 -0300 +++ b/tests/test-topic-flow-publish-bare.t Thu Jul 27 16:39:43 2023 -0300 @@ -349,11 +349,13 @@ $ hg debugcapabilities $TESTTMP/bare-branch-server | grep topics ext-topics-publish=auto + ext-topics-tns-heads topics topics-namespaces $ hg debugcapabilities ssh://user@dummy/bare-branch-server | grep topics _exttopics_heads ext-topics-publish=auto + ext-topics-tns-heads topics topics-namespaces $ hg serve -R ../bare-branch-server -p $HGPORT -d --pid-file hg.pid @@ -361,6 +363,7 @@ $ hg debugcapabilities http://localhost:$HGPORT | grep topics _exttopics_heads ext-topics-publish=auto + ext-topics-tns-heads topics topics-namespaces $ killdaemons.py