Mercurial > evolve
diff hgext3rd/topic/server.py @ 6548:445240ccb701
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.
author | Anton Shestakov <av6@dwimlabs.net> |
---|---|
date | Thu, 27 Jul 2023 16:39:43 -0300 |
parents | a87abe69a2f8 |
children | 2d3771d61068 |
line wrap: on
line diff
--- 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)