# HG changeset patch # User Anton Shestakov # Date 1697657828 10800 # Node ID 144a5814f1cef59bd5ac960e3a51a845b3b3319e # Parent a567e5e90b4f85f018510c1558219ad8c8acd34d# Parent 1ecb25d771df3e3a9a8ad4708747e0ac5998b843 branching: merge into stable in preparation for release diff -r a567e5e90b4f -r 144a5814f1ce .gitlab/issue_templates/new-version.md --- a/.gitlab/issue_templates/new-version.md Wed Aug 16 15:11:43 2023 -0300 +++ b/.gitlab/issue_templates/new-version.md Wed Oct 18 16:37:08 2023 -0300 @@ -1,6 +1,6 @@ This is the actual check list for releasing evolve version X.Y.Z -More details in the [README.rst file](README.rst#L210). +More details in the [README.rst file](README.rst#L219). Preparation @@ -23,9 +23,10 @@ * [ ] build .deb on Heptapod CI for the tagged commit * [ ] add `.dev0` to the `__version__` field * [ ] merge stable into default -* [ ] push the result to https://www.mercurial-scm.org/repo/evolve/ +* [ ] push the result to https://repo.mercurial-scm.org/evolve/ * [ ] send the announcement by email to evolve-testers@mercurial-scm.org * [ ] send the announcement by email to mercurial@mercurial-scm.org * [ ] publish the announcement as a blog on https://octobus.net/blog/ * [ ] update #hg-evolve topic * [ ] tweet about it +* [ ] toot about it diff -r a567e5e90b4f -r 144a5814f1ce CHANGELOG --- a/CHANGELOG Wed Aug 16 15:11:43 2023 -0300 +++ b/CHANGELOG Wed Oct 18 16:37:08 2023 -0300 @@ -1,17 +1,40 @@ Changelog ========= -11.0.3 - in progress +11.1.0 - in progress -------------------- + * remove deprecated evolve.serveronly extension, evolve extension is + recommended for all users, clients and servers + * evolve: don't warn about topics while resolving public content-divergence -topic (1.0.3) + * evolve, pullbundle: drop compatibility with Mercurial 4.8 + +topic (1.1.0) + + * remove deprecated serverminitopic extension, topic extension is recommended + for all users, clients and servers + + * pick: update commit message hashes like other rewrite commands - * topic: only set topic on workingcommitctx if it doesn't already have one + * topic namespaces: add `experimental.tns-allow-rewrite` config option to + check topic namespace before rewriting changesets (known limitations: does + not prevent rebase and histedit from editing changesets outside of + configured topic namespaces on Mercurial 5.2 and older) + * topic namespaces: add `experimental.tns-default-pull-namespaces` config + option to pull only certain changesets by default + * topic namespaces: teach `hg import` and `hg export` to handle topic + namespaces + * topic namespaces: invalidate topic namespace cache in + repo.invalidatecaches() + + * topic: only set topic on workingcommitctx if it doesn't already have one, + making `hg import` always prioritize patch metadata * topic: properly process revbranchcache before sending it to peers (issue6841) - * topic: invalidate topic namespace cache in repo.invalidatecaches() + + * drop compatibility with Mercurial 4.8 11.0.2 -- 2023-07-05 -------------------- diff -r a567e5e90b4f -r 144a5814f1ce README.rst --- a/README.rst Wed Aug 16 15:11:43 2023 -0300 +++ b/README.rst Wed Oct 18 16:37:08 2023 -0300 @@ -87,19 +87,6 @@ * make sure evolve is installed for the same version of Python that you use for running Mercurial (``hg debuginstall | grep Python``). -Server-only Setup -================= - -It is possible to enable a smaller subset of the features aimed at servers that -simply serve repositories:: - - $ hg config --edit # add these two lines: - [extensions] - evolve.serveronly = - -It skips the additions of the new commands and local UI messages that might add -performance overhead. - Extension Purpose ================= diff -r a567e5e90b4f -r 144a5814f1ce debian/control --- a/debian/control Wed Aug 16 15:11:43 2023 -0300 +++ b/debian/control Wed Oct 18 16:37:08 2023 -0300 @@ -7,7 +7,7 @@ Pierre-Yves David , Standards-Version: 4.3.0 Build-Depends: - mercurial (>= 4.8), + mercurial (>= 4.9), python3, debhelper (>= 10), dh-python, @@ -26,7 +26,7 @@ ${python3:Depends}, ${misc:Depends}, ${sphinxdoc:Depends}, - mercurial (>= 4.8), + mercurial (>= 4.9), Built-Using: ${sphinxdoc:Built-Using} Description: evolve extension for Mercurial This package provides the experimental "evolve" extension for the Mercurial diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/__init__.py --- a/hgext3rd/evolve/__init__.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/__init__.py Wed Oct 18 16:37:08 2023 -0300 @@ -14,9 +14,6 @@ - enable the changeset-evolution feature for Mercurial, - improves some aspect of the early implementation in Mercurial core, -Note that a version dedicated to server usage only (no local working copy) is -available as 'evolve.serveronly'. - While many feature related to changeset evolution are directly handled by core this extensions contains significant additions recommended to any user of changeset evolution. @@ -33,7 +30,7 @@ backported to older version of Mercurial by this extension. Some older experimental protocols are also supported for a longer time in the extension to help people transitioning. (The extension is currently compatible down to -Mercurial version 4.8). +Mercurial version 4.9). New Config:: @@ -490,9 +487,14 @@ @eh.uisetup def _installalias(ui): + odiffalias = b"diff --hidden --rev 'limit(predecessors(.),1)' --rev ." if ui.config(b'alias', b'odiff', None) is None: ui.setconfig(b'alias', b'odiff', - b"diff --hidden --rev 'limit(predecessors(.),1)' --rev .", + odiffalias, + b'evolve') + if ui.config(b'alias', b'obsdiff', None) is None: + ui.setconfig(b'alias', b'obsdiff', + odiffalias, b'evolve') ##################################################################### diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/cmdrewrite.py --- a/hgext3rd/evolve/cmdrewrite.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/cmdrewrite.py Wed Oct 18 16:37:08 2023 -0300 @@ -1417,9 +1417,10 @@ def _dopick(ui, repo, pickstate, origctx): """shared logic for performing or continuing a pick""" overrides = {(b'phases', b'new-commit'): origctx.phase()} + new_desc = evolvecmd._rewrite_commit_message_hashes(repo, + origctx.description()) with repo.ui.configoverride(overrides, b'pick'): - newnode = repo.commit(text=origctx.description(), - user=origctx.user(), + newnode = repo.commit(text=new_desc, user=origctx.user(), date=origctx.date(), extra=origctx.extra()) compat.setbranch(repo, origctx.branch()) diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/compat.py --- a/hgext3rd/evolve/compat.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/compat.py Wed Oct 18 16:37:08 2023 -0300 @@ -21,6 +21,7 @@ node, obsolete, pycompat, + rewriteutil, scmutil, util, ) @@ -559,3 +560,26 @@ else: # hg <= 5.6 (527ce85c2e60) StateError = error.Abort + +try: + retained_extras_on_rebase = rewriteutil.retained_extras_on_rebase + preserve_extras_on_rebase = rewriteutil.preserve_extras_on_rebase +except AttributeError: + # hg <= 6.4 (cbcbf63b6dbf) + retained_extras_on_rebase = { + b'source', + b'intermediate-source', + } + + def preserve_extras_on_rebase(old_ctx, new_extra): + """preserve the relevant `extra` entries from old_ctx on rebase-like operations + """ + old_extra = old_ctx.extra() + for key in retained_extras_on_rebase: + value = old_extra.get(key) + if value is not None: + new_extra[key] = value + + # give other extensions an opportunity to collaborate + rewriteutil.retained_extras_on_rebase = retained_extras_on_rebase + rewriteutil.preserve_extras_on_rebase = preserve_extras_on_rebase diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/evolvecmd.py --- a/hgext3rd/evolve/evolvecmd.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/evolvecmd.py Wed Oct 18 16:37:08 2023 -0300 @@ -959,18 +959,9 @@ _finalizerelocate(repo, orig, dest, nodenew, tr, category, evolvestate) return nodenew -# This is copied from hgext.rebase._savegraft() -def _savegraft(ctx, extra): - s = ctx.extra().get(b'source', None) - if s is not None: - extra[b'source'] = s - s = ctx.extra().get(b'intermediate-source', None) - if s is not None: - extra[b'intermediate-source'] = s - def _relocatecommit(repo, orig, dest, pctx, keepbranch, commitmsg, update): extra = {} - _savegraft(orig, extra) + compat.preserve_extras_on_rebase(orig, extra) extra[b'rebase_source'] = orig.hex() targetphase = max(orig.phase(), phases.draft) configoverrides = { @@ -2201,7 +2192,7 @@ ctx = orig extra = {} - _savegraft(ctx, extra) + compat.preserve_extras_on_rebase(orig, extra) extra[b'rebase_source'] = orig.hex() user = ctx.user() diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/metadata.py --- a/hgext3rd/evolve/metadata.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/metadata.py Wed Oct 18 16:37:08 2023 -0300 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -__version__ = b'11.0.3.dev0' -testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5' -minimumhgversion = b'4.8' +__version__ = b'11.1.0.dev0' +testedwith = b'4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5' +minimumhgversion = b'4.9' buglink = b'https://bz.mercurial-scm.org/' diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/rewriteutil.py --- a/hgext3rd/evolve/rewriteutil.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/rewriteutil.py Wed Oct 18 16:37:08 2023 -0300 @@ -11,6 +11,8 @@ # happy one piece of it (and hopefully, able to reuse it in other core # commands). +import functools + from mercurial import ( cmdutil, commands, @@ -60,8 +62,13 @@ can be used to control the commit message. """ + if not pycompat.ispy3 and isinstance(corerewriteutil.precheck, functools.partial): + # inspect.getargspec() on py2 cannot inspect functools.partial objects + # directly, so we need to provide it with the underlying function + args = pycompat.getargspec(corerewriteutil.precheck.func).args + else: + args = pycompat.getargspec(corerewriteutil.precheck).args # hg <= 6.1 (d4752aeb20f1) - args = pycompat.getargspec(corerewriteutil.precheck).args if r'check_divergence' in args: return corerewriteutil.precheck(repo, revs, action, check_divergence=check_divergence) diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/serveronly.py --- a/hgext3rd/evolve/serveronly.py Wed Aug 16 15:11:43 2023 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -'''enable experimental obsolescence feature of Mercurial (DEPRECATED) - -OBSOLESCENCE IS AN EXPERIMENTAL FEATURE MAKE SURE YOU UNDERSTOOD THE INVOLVED -CONCEPT BEFORE USING IT. - -! THIS EXTENSION IS INTENDED FOR SERVER SIDE ONLY USAGE ! - -For client side usages it is recommended to use the evolve extension for -improved user interface.''' - -from __future__ import absolute_import - -import sys -import os - -from mercurial import obsolete - -try: - from . import ( - compat, - exthelper, - metadata, - obscache, - obsexchange, - ) -except (ValueError, ImportError) as exc: - if (isinstance(exc, ValueError) - and str(exc) != b'Attempted relative import in non-package'): - raise - # extension imported using direct path - sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) - from evolve import ( - compat, - exthelper, - metadata, - obscache, - obsexchange, - ) - -__version__ = metadata.__version__ -testedwith = metadata.testedwith -minimumhgversion = metadata.minimumhgversion -buglink = metadata.buglink - -eh = exthelper.exthelper() -eh.merge(compat.eh) -eh.merge(obscache.eh) -eh.merge(obsexchange.eh) -uisetup = eh.finaluisetup -extsetup = eh.finalextsetup -reposetup = eh.finalreposetup -cmdtable = eh.cmdtable -configtable = eh.configtable - -@eh.reposetup -def default2evolution(ui, repo): - evolveopts = repo.ui.configlist(b'experimental', b'evolution') - if not evolveopts: - evolveopts = b'all' - repo.ui.setconfig(b'experimental', b'evolution', evolveopts, b'evolve') - if obsolete.isenabled(repo, b'exchange'): - # if no config explicitly set, disable bundle1 - if not isinstance(repo.ui.config(b'server', b'bundle1'), bytes): - repo.ui.setconfig(b'server', b'bundle1', False, b'evolve') diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/stablerange.py --- a/hgext3rd/evolve/stablerange.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/stablerange.py Wed Oct 18 16:37:08 2023 -0300 @@ -417,7 +417,7 @@ } @eh.command( - b'debugstablerange', + b'debug::evo-ext-stable-range', [ (b'r', b'rev', [], b'operate on (rev, 0) ranges for rev in REVS'), (b'', b'subranges', False, b'recursively display data for subranges too'), diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/stablerangecache.py --- a/hgext3rd/evolve/stablerangecache.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/stablerangecache.py Wed Oct 18 16:37:08 2023 -0300 @@ -441,7 +441,7 @@ super(sqlstablerange, self).warmup(repo, upto) @eh.command( - b'debugstablerangecache', + b'debug::evo-ext-stable-range-cache', [] + commands.formatteropts, _(b'')) def debugstablerangecache(ui, repo, **opts): diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/evolve/stablesort.py --- a/hgext3rd/evolve/stablesort.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/evolve/stablesort.py Wed Oct 18 16:37:08 2023 -0300 @@ -293,7 +293,7 @@ return key @eh.command( - b'debugstablesort', + b'debug::evo-ext-stable-sort', [ (b'r', b'rev', [], b'heads to start from'), (b'', b'method', b'branchpoint', b"method used for sorting, one of: " @@ -326,7 +326,7 @@ displayer.close() @eh.command( - b'debugstablesortcache', + b'debug::evo-ext-stable-sort-cache', [] + commands.formatteropts, _(b'')) def debugstablesortcache(ui, repo, **opts): diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/pullbundle.py --- a/hgext3rd/pullbundle.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/pullbundle.py Wed Oct 18 16:37:08 2023 -0300 @@ -93,8 +93,8 @@ from mercurial.i18n import _ __version__ = b'0.2.0.dev' -testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1' -minimumhgversion = b'4.8' +testedwith = b'4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3' +minimumhgversion = b'4.9' buglink = b'https://bz.mercurial-scm.org/' cmdtable = {} diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/serverminitopic.py --- a/hgext3rd/serverminitopic.py Wed Aug 16 15:11:43 2023 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,261 +0,0 @@ -"""enable a minimal verison of topic for server (DEPRECATED) - -! This extensions is not actively maintained -! We recommand using the main topic extension instead - -Non publishing repository will see topic as "branch:topic" in the branch field. - -In addition to adding the extensions, the feature must be manually enabled in the config: - - [experimental] - server-mini-topic = yes -""" -import hashlib -import contextlib - -from mercurial import ( - branchmap, - context, - encoding, - extensions, - node, - registrar, - util, -) - -from mercurial import wireprotov1server - -if util.safehasattr(registrar, 'configitem'): - - configtable = {} - configitem = registrar.configitem(configtable) - configitem(b'experimental', b'server-mini-topic', - default=False, - ) - -# nodemap.get and index.[has_node|rev|get_rev] -# hg <= 5.2 (02802fa87b74) -def getgetrev(cl): - """Returns index.get_rev or nodemap.get (for pre-5.3 Mercurial).""" - if util.safehasattr(cl.index, 'get_rev'): - return cl.index.get_rev - return cl.nodemap.get - -# hg <= 5.4 (e2d17974a869) -def nonpublicphaseroots(repo): - if util.safehasattr(repo._phasecache, 'nonpublicphaseroots'): - return repo._phasecache.nonpublicphaseroots(repo) - return set().union( - *[roots for roots in repo._phasecache.phaseroots[1:] if roots] - ) - -def hasminitopic(repo): - """true if minitopic is enabled on the repository - - (The value is cached on the repository) - """ - enabled = getattr(repo, '_hasminitopic', None) - if enabled is None: - enabled = (repo.ui.configbool(b'experimental', b'server-mini-topic') - and not repo.publishing()) - repo._hasminitopic = enabled - return enabled - -### make topic visible though "ctx.branch()" - -def topicbranch(orig, self): - branch = orig(self) - if hasminitopic(self._repo) and self.phase(): - topic = self._changeset.extra.get(b'topic') - if topic is not None: - topic = encoding.tolocal(topic) - branch = b'%s:%s' % (branch, topic) - return branch - -### avoid caching topic data in rev-branch-cache - -class revbranchcacheoverlay(object): - """revbranch mixin that don't use the cache for non public changeset""" - - def _init__(self, *args, **kwargs): - super(revbranchcacheoverlay, self).__init__(*args, **kwargs) - if r'branchinfo' in vars(self): - del self.branchinfo - - def branchinfo(self, rev, changelog=None): - """return branch name and close flag for rev, using and updating - persistent cache.""" - phase = self._repo._phasecache.phase(self._repo, rev) - if phase: - ctx = self._repo[rev] - return ctx.branch(), ctx.closesbranch() - return super(revbranchcacheoverlay, self).branchinfo(rev) - -def reposetup(ui, repo): - """install a repo class with a special revbranchcache""" - - if hasminitopic(repo): - repo = repo.unfiltered() - - class minitopicrepo(repo.__class__): - """repository subclass that install the modified cache""" - - def revbranchcache(self): - if self._revbranchcache is None: - cache = super(minitopicrepo, self).revbranchcache() - - class topicawarerbc(revbranchcacheoverlay, cache.__class__): - pass - cache.__class__ = topicawarerbc - if r'branchinfo' in vars(cache): - del cache.branchinfo - self._revbranchcache = cache - return self._revbranchcache - - repo.__class__ = minitopicrepo - -### topic aware branch head cache - -def _phaseshash(repo, maxrev): - """uniq ID for a phase matching a set of rev""" - revs = set() - cl = repo.changelog - fr = cl.filteredrevs - getrev = getgetrev(cl) - for n in nonpublicphaseroots(repo): - r = getrev(n) - if r not in fr and r < maxrev: - revs.add(r) - key = node.nullid - revs = sorted(revs) - if revs: - s = hashlib.sha1() - for rev in revs: - s.update(b'%d;' % rev) - key = s.digest() - return key - -# needed to prevent reference used for 'super()' call using in branchmap.py to -# no go into cycle. (yes, URG) -_oldbranchmap = branchmap.branchcache - -@contextlib.contextmanager -def oldbranchmap(): - previous = branchmap.branchcache - try: - branchmap.branchcache = _oldbranchmap - yield - finally: - branchmap.branchcache = previous - -_publiconly = set([ - b'base', - b'immutable', -]) - -def mighttopic(repo): - return hasminitopic(repo) and repo.filtername not in _publiconly - -class _topiccache(branchmap.branchcache): # combine me with branchmap.branchcache - @classmethod - def fromfile(cls, repo): - orig = super(_topiccache, cls).fromfile - return wrapread(orig, repo) - - def __init__(self, *args, **kwargs): - # super() call may fail otherwise - with oldbranchmap(): - super(_topiccache, self).__init__(*args, **kwargs) - self.phaseshash = None - - def copy(self): - """return an deep copy of the branchcache object""" - if util.safehasattr(self, '_entries'): - _entries = self._entries - else: - # hg <= 4.9 (624d6683c705+b137a6793c51) - _entries = self - args = (_entries, self.tipnode, self.tiprev, self.filteredhash, - self._closednodes) - if util.safehasattr(self, '_repo'): - # hg <= 5.7 (6266d19556ad) - args = (self._repo,) + args - new = self.__class__(*args) - new.phaseshash = self.phaseshash - return new - - def validfor(self, repo): - """Is the cache content valid regarding a repo - - - False when cached tipnode is unknown or if we detect a strip. - - True when cache is up to date or a subset of current repo.""" - valid = super(_topiccache, self).validfor(repo) - if not valid: - return False - elif self.phaseshash is None: - # phasehash at None means this is a branchmap - # coming from a public only set - return True - else: - try: - valid = self.phaseshash == _phaseshash(repo, self.tiprev) - return valid - except IndexError: - return False - - def write(self, repo): - # we expect (hope) mutable set to be small enough to be that computing - # it all the time will be fast enough - if not mighttopic(repo): - super(_topiccache, self).write(repo) - - def update(self, repo, revgen): - """Given a branchhead cache, self, that may have extra nodes or be - missing heads, and a generator of nodes that are strictly a superset of - heads missing, this function updates self to be correct. - """ - super(_topiccache, self).update(repo, revgen) - if mighttopic(repo): - self.phaseshash = _phaseshash(repo, self.tiprev) - -def wrapread(orig, repo): - # Avoiding to write cache for filter where topic applies is a good step, - # but we need to also avoid reading it. Existing branchmap cache might - # exists before the turned the feature on. - if mighttopic(repo): - return None - return orig(repo) - -# advertise topic capabilities - -def wireprotocaps(orig, repo, proto): - caps = orig(repo, proto) - if hasminitopic(repo): - caps.append(b'topics') - return caps - -# wrap the necessary bit - -def wrapclass(container, oldname, new): - old = getattr(container, oldname) - if not issubclass(old, new): - targetclass = new - # check if someone else already wrapped the class and handle that - if not issubclass(new, old): - class targetclass(new, old): - pass - setattr(container, oldname, targetclass) - current = getattr(container, oldname) - assert issubclass(current, new), (current, new, targetclass) - -def uisetup(ui): - wrapclass(branchmap, 'branchcache', _topiccache) - try: - # hg <= 4.9 (3461814417f3) - extensions.wrapfunction(branchmap, 'read', wrapread) - except AttributeError: - # Mercurial 5.0; branchcache.fromfile now takes care of this - # which is alredy defined on _topiccache - pass - extensions.wrapfunction(wireprotov1server, '_capabilities', wireprotocaps) - extensions.wrapfunction(context.changectx, 'branch', topicbranch) diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/topic/__init__.py Wed Oct 18 16:37:08 2023 -0300 @@ -165,6 +165,7 @@ from mercurial.i18n import _ from mercurial import ( bookmarks, + bundlerepo, changelog, cmdutil, commands, @@ -186,7 +187,9 @@ phases, pycompat, registrar, + rewriteutil, scmutil, + smartset, templatefilters, util, ) @@ -233,10 +236,10 @@ b'log.topic': b'green_background', } -__version__ = b'1.0.3.dev0' +__version__ = b'1.1.0.dev0' -testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5' -minimumhgversion = b'4.8' +testedwith = b'4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5' +minimumhgversion = b'4.9' buglink = b'https://bz.mercurial-scm.org/' configtable = {} @@ -269,6 +272,22 @@ configitem(b'_internal', b'tns-publish', default=False, ) +# used for signaling that the current command has explicit target arguments +# (e.g. --rev or --branch) and we should ignore tns-default-* config +configitem(b'_internal', b'tns-explicit-target', + default=False, +) +configitem(b'devel', b'tns-report-transactions', + default=lambda: [], +) +# used for allowing users to rewrite history only in their "own" topic +# namespaces +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, ) @@ -291,24 +310,27 @@ default=None, ) if (b'devel' not in ui._knownconfig - or not ui._knownconfig[b'devel'].get(b'random')): + or not ui._knownconfig[b'devel'].get(b'randomseed')): extraitem(b'devel', b'randomseed', default=None, ) def _contexttns(self, force=False): if not force and not self.mutable(): - return b'default' + return b'none' cache = getattr(self._repo, '_tnscache', None) # topic loaded, but not enabled (eg: multiple repo in the same process) if cache is None: - return b'default' + return b'none' + # topic namespace is meaningless when topic is not set + if not self.topic(force): + return b'none' if self.rev() is None: # don't cache volatile ctx instances that aren't stored on-disk yet - return self.extra().get(b'topic-namespace', b'default') + return self.extra().get(b'topic-namespace', b'none') tns = cache.get(self.rev()) if tns is None: - tns = self.extra().get(b'topic-namespace', b'default') + tns = self.extra().get(b'topic-namespace', b'none') self._repo._tnscache[self.rev()] = tns return tns @@ -430,6 +452,70 @@ or (missing and self.deleted()) ) +def find_affected_tns(repo, tr): + origrepolen = tr.changes[b'origrepolen'] + unfi = repo.unfiltered() + + affected = set() + # These are the new changesets that weren't in the repo before this + # transaction + for rev in smartset.spanset(repo, start=origrepolen): + ctx = unfi[rev] + tns = ctx.topic_namespace() + affected.add(tns) + + # These are the changesets obsoleted by this transaction + for rev in obsutil.getobsoleted(repo, tr): + ctx = unfi[rev] + tns = ctx.topic_namespace() + affected.add(tns) + + # Phase movements, we only care about: + # - publishing changesets (since they lose topic namespace) + # - forcefully making changesets draft again + # - turning secret changesets draft and making them visible to peers + tnsphases = (phases.secret, phases.draft) + phasechanges = tr.changes[b'phases'] + if isinstance(phasechanges, dict): + # hg <= 5.3 (fdc802f29b2c) + phasechanges = [((k,), v) for k, v in phasechanges.items()] + for revs, (old, new) in phasechanges: + if old not in tnsphases and new not in tnsphases: + # Skip phase movement if there is no phase (old or new) that has + # visible topic namespace (i.e. draft and secret) + continue + revs = [rev for rev in revs if rev < origrepolen] + for rev in revs: + ctx = unfi[rev] + tns = ctx.topic_namespace(force=True) + affected.add(tns) + + # We want to detect any bookmark movement, even within one topic namespace + for name, nodes in tr.changes[b'bookmarks'].items(): + for n in nodes: + if n is not None and n in unfi: + ctx = unfi[n] + tns = ctx.topic_namespace() + affected.add(tns) + + # We don't care about changesets without topic namespace + affected.discard(b'none') + + tr.changes[b'tns'] = affected + report_affected_tns(repo, tr) + +def report_affected_tns(repo, tr): + report = set(repo.ui.configlist(b'devel', b'tns-report-transactions')) + # transaction names sometimes also have a URL after a newline byte + trnames = (trname.partition(b'\n')[0] for trname in tr._names) + if b'*' not in report: + # * matches any transaction + if not any(trname in report for trname in trnames): + return + + if tr.changes[b'tns']: + repo.ui.status(b'topic namespaces affected: %s\n' % b' '.join(sorted(tr.changes[b'tns']))) + def uisetup(ui): destination.modsetup(ui) discovery.modsetup(ui) @@ -506,8 +592,37 @@ extensions.wrapfunction(histedit.histeditaction, 'applychange', applychangewrap) + # Wrapping precheck() both in core and in evolve to make sure all rewrite + # operations that could use precheck() are covered + extensions.wrapfunction(rewriteutil, 'precheck', wrapprecheck) + try: + evolve = extensions.find(b'evolve') + extensions.wrapfunction(evolve.rewriteutil, 'precheck', wrapprecheck) + except (KeyError, AttributeError): + pass + server.setupserver(ui) + # We want bundle repos to also have caches for topic extension, because we + # want to, for example, see topic and topic namespaces in `hg incoming` + # regardless if the bundle repo has topic extension, as long as local repo + # has topic enabled. + class topicbundlerepo(bundlerepo.bundlerepository): + @util.propertycache + def _tnscache(self): + return {} + + @util.propertycache + def _topiccache(self): + return {} + + def invalidatecaches(self): + self._tnscache.clear() + self._topiccache.clear() + super(topicbundlerepo, self).invalidatecaches() + + bundlerepo.bundlerepository = topicbundlerepo + def reposetup(ui, repo): if not isinstance(repo, localrepo.localrepository): return # this can be a peer in the ssh case (puzzling) @@ -541,6 +656,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): @@ -568,15 +684,16 @@ def topic_namespaces(self): if self._topic_namespaces is not None: return self._topic_namespaces - namespaces = set([self.currenttns]) + namespaces = set([b'none', self.currenttns]) for c in self.set(b'not public()'): namespaces.add(c.topic_namespace()) + namespaces.remove(b'none') self._topic_namespaces = namespaces return namespaces @property def currenttns(self): - return self.vfs.tryread(b'topic-namespace') or b'default' + return self.vfs.tryread(b'topic-namespace') or b'none' @util.propertycache def _topiccache(self): @@ -657,6 +774,20 @@ 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 = [] + entries = compat.bcentries(self._repo.branchmaptns()) + for branch, nodes in compat.branchmapitems(entries): + namedbranch, tns, topic = common.parsefqbn(branch) + if tns == b'none' or tns in namespaces: + h.extend(nodes) + return h peer.__class__ = topicpeer return peer @@ -670,21 +801,21 @@ if self.ui.configbool(b'experimental', b'enforce-single-head'): if util.safehasattr(tr, '_validator'): # hg <= 5.3 (36f08ae87ef6) - origvalidator = tr._validator + origvalidator_single_head = tr._validator - def _validate(tr2): + def _validate_single_head(tr2): repo = reporef() flow.enforcesinglehead(repo, tr2) def validator(tr2): - _validate(tr2) - return origvalidator(tr2) + _validate_single_head(tr2) + return origvalidator_single_head(tr2) if util.safehasattr(tr, '_validator'): # hg <= 5.3 (36f08ae87ef6) tr._validator = validator else: - tr.addvalidator(b'000-enforce-single-head', _validate) + tr.addvalidator(b'000-enforce-single-head', _validate_single_head) topicmodeserver = self.ui.config(b'experimental', b'topic-mode.server', b'ignore') @@ -694,21 +825,21 @@ if (topicmodeserver != b'ignore' and ispush): if util.safehasattr(tr, '_validator'): # hg <= 5.3 (36f08ae87ef6) - origvalidator = tr._validator + origvalidator_untopiced = tr._validator - def _validate(tr2): + def _validate_untopiced(tr2): repo = reporef() flow.rejectuntopicedchangeset(repo, tr2) def validator(tr2): - _validate(tr2) - return origvalidator(tr2) + _validate_untopiced(tr2) + return origvalidator_untopiced(tr2) if util.safehasattr(tr, '_validator'): # hg <= 5.3 (36f08ae87ef6) tr._validator = validator else: - tr.addvalidator(b'000-reject-untopiced', _validate) + tr.addvalidator(b'000-reject-untopiced', _validate_untopiced) elif publishbare and ispush: origclose = tr.close @@ -726,21 +857,40 @@ if not allow_publish: if util.safehasattr(tr, '_validator'): # hg <= 5.3 (36f08ae87ef6) - origvalidator = tr._validator + origvalidator_publish = tr._validator - def _validate(tr2): + def _validate_publish(tr2): repo = reporef() flow.reject_publish(repo, tr2) def validator(tr2): - _validate(tr2) - return origvalidator(tr2) + _validate_publish(tr2) + return origvalidator_publish(tr2) if util.safehasattr(tr, '_validator'): # hg <= 5.3 (36f08ae87ef6) tr._validator = validator else: - tr.addvalidator(b'000-reject-publish', _validate) + tr.addvalidator(b'000-reject-publish', _validate_publish) + + if util.safehasattr(tr, '_validator'): + # hg <= 5.3 (36f08ae87ef6) + origvalidator_affected_tns = tr._validator + + def _validate_affected_tns(tr2): + repo = reporef() + find_affected_tns(repo, tr2) + + def validator(tr2): + result = origvalidator_affected_tns(tr2) + _validate_affected_tns(tr2) + return result + + if util.safehasattr(tr, '_validator'): + # hg <= 5.3 (36f08ae87ef6) + tr._validator = validator + else: + tr.addvalidator(b'999-find-affected-tns', _validate_affected_tns) # real transaction start ct = self.currenttopic @@ -818,7 +968,7 @@ self._extra[b'topic-namespace'] = repo.currenttns else: # Default value will be dropped from extra by another hack at the changegroup level - self._extra[b'topic-namespace'] = b'default' + self._extra[b'topic-namespace'] = b'none' if constants.extrakey not in self._extra: if getattr(repo, 'currenttopic', b''): self._extra[constants.extrakey] = repo.currenttopic @@ -829,12 +979,16 @@ def wrapadd(orig, cl, manifest, files, desc, transaction, p1, p2, user, date=None, extra=None, p1copies=None, p2copies=None, filesadded=None, filesremoved=None): - if b'topic-namespace' in extra and extra[b'topic-namespace'] == b'default': + if b'topic-namespace' in extra and extra[b'topic-namespace'] == b'none': extra = extra.copy() del extra[b'topic-namespace'] if constants.extrakey in extra and not extra[constants.extrakey]: extra = extra.copy() del extra[constants.extrakey] + if constants.extrakey not in extra and b'topic-namespace' in extra: + # if topic is not in extra, drop namespace as well + extra = extra.copy() + del extra[b'topic-namespace'] # hg <= 4.9 (0e41f40b01cc) kwargs = {} if p1copies is not None: @@ -1519,14 +1673,14 @@ if repo.ui.configbool(b'_internal', b'keep-topic'): ist0 = True if ((not partial and not branchmerge) or isrebase) and not ist0: - tns = b'default' + tns = b'none' t = b'' pctx = repo[node] if pctx.phase() > phases.public: tns = pctx.topic_namespace() t = pctx.topic() repo.vfs.write(b'topic-namespace', tns) - if tns != b'default' and tns != otns: + if tns != b'none' and tns != otns: repo.ui.status(_(b"switching to topic-namespace %s\n") % tns) repo.vfs.write(b'topic', t) if t and t != ot: @@ -1585,22 +1739,37 @@ ## preserve topic during import/export +def _exporttns(seq, ctx): + tns = ctx.topic_namespace() + if tns != b'none': + return b'EXP-Topic-Namespace %s' % tns + return None + def _exporttopic(seq, ctx): topic = ctx.topic() if topic: return b'EXP-Topic %s' % topic return None +def _importtns(repo, patchdata, extra, opts): + if b'topic-namespace' in patchdata: + extra[b'topic-namespace'] = patchdata[b'topic-namespace'] + def _importtopic(repo, patchdata, extra, opts): if b'topic' in patchdata: extra[b'topic'] = patchdata[b'topic'] def setupimportexport(ui): """run at ui setup time to install import/export logic""" + cmdutil.extraexport.append(b'topic-namespace') + cmdutil.extraexportmap[b'topic-namespace'] = _exporttns cmdutil.extraexport.append(b'topic') cmdutil.extraexportmap[b'topic'] = _exporttopic + cmdutil.extrapreimport.append(b'topic-namespace') + cmdutil.extrapreimportmap[b'topic-namespace'] = _importtns cmdutil.extrapreimport.append(b'topic') cmdutil.extrapreimportmap[b'topic'] = _importtopic + patch.patchheadermap.append((b'EXP-Topic-Namespace', b'topic-namespace')) patch.patchheadermap.append((b'EXP-Topic', b'topic')) ## preserve topic during split @@ -1618,13 +1787,33 @@ original(repo, ui, prev, ctx) # Restore the topic if need - if tns: + if tns != b'none': _changecurrenttns(repo, tns) if topic: _changecurrenttopic(repo, topic) +def wrapprecheck(orig, repo, revs, action=b'rewrite', check_divergence=True): + # hg <= 6.1 (d4752aeb20f1) + args = pycompat.getargspec(orig).args + if r'check_divergence' in args: + orig(repo, revs, action, check_divergence=check_divergence) + else: + orig(repo, revs, action) + + # TODO: at some point in future the default will change from '*' to the + # default topic namespace for the current user + allow = set(repo.ui.configlist(b'experimental', b'tns-allow-rewrite', [b'*'])) + if b'*' not in allow: + namespaces = set(repo[rev].topic_namespace() for rev in revs) + disallowed = namespaces - allow + if disallowed: + msg = _(b"refusing to %s changesets with these topic namespaces: %s") + msg %= (action, b' '.join(disallowed)) + hint = _(b"modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces") + raise compat.InputError(msg, hint=hint) + def _changecurrenttns(repo, tns): - if tns: + if tns != b'none': with repo.wlock(): repo.vfs.write(b'topic-namespace', tns) else: @@ -1639,7 +1828,7 @@ if opts.get('clear'): if tns: raise error.Abort(_(b"cannot use --clear when setting a topic namespace")) - tns = None + tns = b'none' elif not tns: ui.write(b'%s\n' % repo.currenttns) return @@ -1652,7 +1841,7 @@ scmutil.checknewlabel(repo, tns, b'topic namespace') ctns = repo.currenttns _changecurrenttns(repo, tns) - if ctns == b'default' and tns: + if ctns == b'none' and tns != b'none': repo.ui.status(_(b'marked working directory as topic namespace: %s\n') % tns) diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/topic/common.py --- a/hgext3rd/topic/common.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/topic/common.py Wed Oct 18 16:37:08 2023 -0300 @@ -11,21 +11,21 @@ """parse branch//namespace/topic string into branch, namespace and topic >>> parsefqbn(b'branch//topic') - ('branch', 'default', 'topic') + ('branch', 'none', 'topic') >>> parsefqbn(b'//namespace/topic') ('default', 'namespace', 'topic') >>> parsefqbn(b'branch//') - ('branch', 'default', '') + ('branch', 'none', '') >>> parsefqbn(b'//namespace/') ('default', 'namespace', '') >>> parsefqbn(b'/topic') - ('/topic', 'default', '') + ('/topic', 'none', '') >>> parsefqbn(b'//topic') - ('default', 'default', 'topic') + ('default', 'none', 'topic') >>> parsefqbn(b'branch//namespace/topic') ('branch', 'namespace', 'topic') >>> parsefqbn(b'file:///tmp/branch//') - ('file:///tmp/branch', 'default', '') + ('file:///tmp/branch', 'none', '') >>> parsefqbn(b'http://example.com/branch//namespace/topic') ('http://example.com/branch', 'namespace', 'topic') """ @@ -39,7 +39,7 @@ tns, sep, topic = other.partition(b'/') if not sep: # when there's no / in the rest of the string, there can only be topic - tns, topic = b'default', tns + tns, topic = b'none', tns return branch, tns, topic def formatfqbn(branch=b'', namespace=b'', topic=b'', short=True): @@ -70,7 +70,7 @@ """ result = b'' showbranch = True # branch and not (short and branch == b'default') - shownamespace = namespace and not (short and namespace == b'default') + shownamespace = namespace and not (short and namespace == b'none') if short and not showbranch and not shownamespace and not topic: # if there's nothing to show, show at least branch showbranch = True diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/topic/compat.py --- a/hgext3rd/topic/compat.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/topic/compat.py Wed Oct 18 16:37:08 2023 -0300 @@ -49,14 +49,29 @@ ) def overridecommitstatus(overridefn): - if r'tip' in cmdutil.commitstatus.__code__.co_varnames: + code = cmdutil.commitstatus.__code__ + if r'opts' in code.co_varnames[code.co_argcount:]: + # commitstatus(..., **opts) extensions.wrapfunction(cmdutil, 'commitstatus', overridefn) + elif r'tip' in code.co_varnames: + # hg <= 6.5 (489268c8ee7e) + def _override(orig, repo, node, branch, bheads=None, tip=None, opts=None): + def _orig(repo, node, branch, bheads=None, tip=None, **opts): + opts = pycompat.byteskwargs(opts) + return orig(repo, node, branch, bheads=bheads, tip=tip, opts=opts) + opts = pycompat.strkwargs(opts) + return overridefn(_orig, repo, node, branch, bheads=bheads, tip=tip, **opts) + extensions.wrapfunction(cmdutil, 'commitstatus', _override) else: # hg <= 5.6 (976b26bdd0d8) def _override(orig, repo, node, branch, bheads=None, opts=None): - def _orig(repo, node, branch, bheads=None, tip=None, opts=None): + def _orig(repo, node, branch, bheads=None, **opts): + opts = pycompat.byteskwargs(opts) return orig(repo, node, branch, bheads=bheads, opts=opts) - return overridefn(_orig, repo, node, branch, bheads=bheads, tip=None, opts=opts) + if opts is None: + opts = {} + opts = pycompat.strkwargs(opts) + return overridefn(_orig, repo, node, branch, bheads=bheads, **opts) extensions.wrapfunction(cmdutil, 'commitstatus', _override) if util.safehasattr(error, 'InputError'): diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/topic/discovery.py --- a/hgext3rd/topic/discovery.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/topic/discovery.py Wed Oct 18 16:37:08 2023 -0300 @@ -12,6 +12,7 @@ encoding, exchange, extensions, + hg, scmutil, util, wireprototypes, @@ -183,9 +184,9 @@ """copied from wireprotov1server.branchmap()""" if not common.hastopicext(repo): return wireprotov1server.branchmap(repo, proto) - branchmaptns = repo.branchmaptns() heads = [] - for branch, nodes in branchmaptns.items(): + entries = compat.bcentries(repo.branchmaptns()) + for branch, nodes in compat.branchmapitems(entries): branchname = urlreq.quote(encoding.fromlocal(branch)) branchnodes = wireprototypes.encodelist(nodes) heads.append(b'%s %s' % (branchname, branchnodes)) @@ -248,7 +249,7 @@ data = {} for b in repo.branchmap().iterbranches(): namedbranch, tns, topic = common.parsefqbn(b[0]) - if tns != b'default' or topic: + if tns != b'none' or topic: continue oldheads = [repo[n].rev() for n in b[1]] newheads = filterfn(repo, oldheads) @@ -360,6 +361,24 @@ with repo.ui.configoverride(overrides, b'topic-namespaces'): orig(repo, bundler, outgoing) +def wraphgpeer(orig, uiorrepo, opts, *args, **kwargs): + """hg.peer() that checks if there are explicit arguments for e.g. pull""" + peer = orig(uiorrepo, opts, *args, **kwargs) + if any(opts.get(k) for k in (b'rev', b'bookmark', b'branch')): + peer.ui.setconfig(b'_internal', b'tns-explicit-target', True, b'topic-namespaces') + return peer + +def wraphgremoteui(orig, src, opts): + """hg.remoteui() that copies tns-related config options to peer ui""" + dst = orig(src, opts) + if util.safehasattr(src, 'baseui'): # looks like a repository + src = src.ui + # we need to copy topic namespaces from local config to peer ui, since it + # needs to be accessible for peer command executors + namespaces = src.configlist(b'experimental', b'tns-default-pull-namespaces', [b'*']) + dst.setconfig(b'experimental', b'tns-default-pull-namespaces', namespaces, b'copied') + return dst + def modsetup(ui): """run at uisetup time to install all destinations wrapping""" extensions.wrapfunction(discovery, '_headssummary', _headssummary) @@ -385,3 +404,5 @@ extensions.wrapfunction(bundle2, 'addpartrevbranchcache', wrapaddpartrevbranchcache) extensions.wrapfunction(exchange, '_pushb2phases', _pushb2phases) exchange.b2partsgenmapping[b'phase'] = exchange._pushb2phases + extensions.wrapfunction(hg, 'peer', wraphgpeer) + extensions.wrapfunction(hg, 'remoteui', wraphgremoteui) diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/topic/revset.py --- a/hgext3rd/topic/revset.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/topic/revset.py Wed Oct 18 16:37:08 2023 -0300 @@ -25,7 +25,7 @@ def topicnamespaceset(repo, subset, x): """All changesets with the specified topic namespace or the topic namespaces of the given changesets. Without the argument, all changesets - with any non-default topic namespace. + with any non-empty topic namespace. Pattern matching is supported for `string`. See :hg:`help revisions.patterns`. @@ -35,7 +35,7 @@ mutable = revset._notpublic(repo, revset.fullreposet(repo), ()) if not args: - return (subset & mutable).filter(lambda r: repo[r].topic_namespace() != b'default') + return (subset & mutable).filter(lambda r: repo[r].topic_namespace() != b'none') try: tns = getstringstrict(args[0], b'') @@ -50,7 +50,7 @@ def matches(r): tns = repo[r].topic_namespace() - if tns == b'default': + if tns == b'none': return False return matcher(tns) @@ -58,11 +58,11 @@ s = revset.getset(repo, revset.fullreposet(repo), x) namespaces = {repo[r].topic_namespace() for r in s} - namespaces.discard(b'default') + namespaces.discard(b'none') def matches(r): tns = repo[r].topic_namespace() - if tns == b'default': + if tns == b'none': return False return tns in namespaces diff -r a567e5e90b4f -r 144a5814f1ce hgext3rd/topic/server.py --- a/hgext3rd/topic/server.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/topic/server.py Wed Oct 18 16:37:08 2023 -0300 @@ -2,10 +2,15 @@ # # 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, + util, wireprototypes, wireprotov1peer, wireprotov1server, @@ -13,6 +18,7 @@ from . import ( common, + compat, constants, ) @@ -58,6 +64,25 @@ 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 = [] + entries = compat.bcentries(repo.branchmaptns()) + for branch, nodes in compat.branchmapitems(entries): + 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 +95,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 +103,48 @@ 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) + if util.safehasattr(wireprotov1peer, 'future'): + # hg <= 5.9 (c424ff4807e6) + class tnspeer(wireprotov1peer.wirepeer): + """ wirepeer that uses `future` class from before c424ff4807e6 """ + @wireprotov1peer.batchable + def tns_heads(self, namespaces): + f = wireprotov1peer.future() + yield {b'namespaces': wireprototypes.encodelist(namespaces)}, f + d = f.value + try: + yield wireprototypes.decodelist(d[:-1]) + except ValueError: + self._abort(error.ResponseError(_(b"unexpected response:"), d)) + else: + class tnspeer(wireprotov1peer.wirepeer): + """ wirepeer that uses newer batchable scheme from c424ff4807e6 """ + @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' + if self._peer.ui.configbool(b'_internal', b'tns-explicit-target', False): + args[b'namespaces'] = [b'*'] + else: + 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 +153,20 @@ 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' + if self._peer.ui.configbool(b'_internal', b'tns-explicit-target', False): + args[b'namespaces'] = [b'*'] + else: + 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 a567e5e90b4f -r 144a5814f1ce hgext3rd/topic/topicmap.py --- a/hgext3rd/topic/topicmap.py Wed Aug 16 15:11:43 2023 -0300 +++ b/hgext3rd/topic/topicmap.py Wed Oct 18 16:37:08 2023 -0300 @@ -97,7 +97,7 @@ other = repo.filtered(topicfilter(repo.filtername)) return orig(self, other, *args, **kwargs) -def commitstatus(orig, repo, node, branch, bheads=None, tip=None, opts=None): +def commitstatus(orig, repo, node, branch, bheads=None, tip=None, **opts): # wrap commit status use the topic branch heads ctx = repo[node] ctxbranch = common.formatfqbn(branch=ctx.branch()) @@ -105,16 +105,14 @@ bheads = repo.branchheads(b"%s:%s" % (branch, ctx.topic())) with discovery.override_context_branch(repo) as repo: - ret = orig(repo, node, branch, bheads=bheads, tip=tip, opts=opts) + ret = orig(repo, node, branch, bheads=bheads, tip=tip, **opts) # logic copy-pasted from cmdutil.commitstatus() - if opts is None: - opts = {} if ctx.topic(): return ret parents = ctx.parents() - if (not opts.get(b'amend') and bheads and node not in bheads and not any( + if (not opts.get('amend') and bheads and node not in bheads and not any( p.node() in bheads and common.formatfqbn(branch=p.branch()) == branch for p in parents )): diff -r a567e5e90b4f -r 144a5814f1ce setup.py --- a/setup.py Wed Aug 16 15:11:43 2023 -0300 +++ b/setup.py Wed Oct 18 16:37:08 2023 -0300 @@ -18,9 +18,6 @@ '''Read version info from a file without importing it''' return get_metadata()['minimumhgversion'] -py_modules = [ - 'hgext3rd.serverminitopic', -] py_packages = [ 'hgext3rd', 'hgext3rd.evolve', @@ -45,7 +42,6 @@ long_description=open(join(dirname(__file__), 'README.rst')).read(), keywords='hg mercurial', license='GPLv2+', - py_modules=py_modules, packages=py_packages, package_dir=py_packagedir, python_requires=py_versions diff -r a567e5e90b4f -r 144a5814f1ce tests/test-cache-corruption.t --- a/tests/test-cache-corruption.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-cache-corruption.t Wed Oct 18 16:37:08 2023 -0300 @@ -152,7 +152,7 @@ 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 0030: 00 00 00 00 |....| - $ hg debugstablesortcache --debug + $ hg debug::evo-ext-stable-sort-cache --debug number of revisions: 3 number of merge: 0 number of jumps: 0 @@ -164,7 +164,7 @@ 0010: 49 c6 55 ea 65 b2 95 e3 00 00 00 0c 00 00 00 00 |I.U.e...........| 0020: 00 00 00 00 00 00 00 00 |........| - $ hg debugstablesortcache --debug + $ hg debug::evo-ext-stable-sort-cache --debug number of revisions: 3 stablesortcache file seems to be corrupted, it will be rebuilt from scratch number of merge: 0 @@ -177,7 +177,7 @@ 0010: 49 c6 55 ea 65 b2 95 e3 00 00 00 18 00 00 00 00 |I.U.e...........| 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - $ hg debugstablesortcache --debug + $ hg debug::evo-ext-stable-sort-cache --debug number of revisions: 3 stablesortcache file seems to be corrupted, it will be rebuilt from scratch number of merge: 0 @@ -305,7 +305,7 @@ 0040: 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 |................| 0050: 00 00 00 00 |....| - $ hg debugstablesortcache --debug + $ hg debug::evo-ext-stable-sort-cache --debug number of revisions: 4 number of merge: 1 number of jumps: 1 @@ -324,7 +324,7 @@ 0020: 00 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 |................| 0030: 01 00 00 00 02 00 00 00 |........| - $ hg debugstablesortcache --debug + $ hg debug::evo-ext-stable-sort-cache --debug number of revisions: 4 stablesortcache file seems to be corrupted, it will be rebuilt from scratch number of merge: 1 @@ -345,7 +345,7 @@ 0030: 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 |................| 0040: 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 |................| - $ hg debugstablesortcache --debug + $ hg debug::evo-ext-stable-sort-cache --debug number of revisions: 4 stablesortcache file seems to be corrupted, it will be rebuilt from scratch number of merge: 1 diff -r a567e5e90b4f -r 144a5814f1ce tests/test-check-sdist.t --- a/tests/test-check-sdist.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-check-sdist.t Wed Oct 18 16:37:08 2023 -0300 @@ -34,8 +34,12 @@ hg-evolve-*.tar.gz (glob) $ tar -tzf hg-evolve-*.tar.gz | sed 's|^hg-evolve-[^/]*/||' | sort > files - $ wc -l files - 362 files + $ egrep '^tests/test-.*\.(t|py)$' files > test-files + $ egrep -v '^tests/test-.*\.(t|py)$' files > other-files + $ wc -l other-files + 148 other-files + $ wc -l test-files + ??? test-files (glob) $ fgrep debian files tests/test-check-debian.t $ fgrep __init__.py files diff -r a567e5e90b4f -r 144a5814f1ce tests/test-check-tag.t --- a/tests/test-check-tag.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-check-tag.t Wed Oct 18 16:37:08 2023 -0300 @@ -23,7 +23,6 @@ > fi > # Here we skip: > # - pullbundle because it usually has no changes (so no version bump) - > # - serverminitopic because it's not actively maintained > if hg grep --rev $node '^__version__ = .*\.dev' hgext3rd/evolve/ hgext3rd/topic/; then > echo "Versions should not end with .dev at tagged revision $node" > fi diff -r a567e5e90b4f -r 144a5814f1ce tests/test-evolve-extras.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-evolve-extras.t Wed Oct 18 16:37:08 2023 -0300 @@ -0,0 +1,42 @@ +Testing retained_extras_on_rebase usage in evolve and modifying it in an extension + + $ . $TESTDIR/testlib/common.sh + + $ hg init repo + $ cd repo + $ cat > .hg/hgrc << EOF + > [extensions] + > evolve = + > EOF + + $ echo apple > a + $ hg ci -qAm 'apple' + $ echo banana > b + $ hg ci -qAm 'banana' --config extensions.commitextras= \ + > --extra useful=b-for-banana \ + > --extra useless=banana-peel + +amending apple + + $ hg prev + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + [0] apple + $ echo apricot > a + $ hg amend -m 'apricot' + 1 new orphan changesets + +the commit still has all extras that we added previously + + $ hg log -r 'desc("banana")' -T '{join(extras, " ")}\n' + *useful=b-for-banana*useless=banana-peel* (glob) + +let's run evolve with our extension + + $ hg --config extensions.retained_extras=${TESTDIR}/testlib/retain-extras-ext.py evolve + move:[1] banana + atop:[2] apricot + +evolving banana retained "useful" and discarded "useless" + + $ hg log -r 'desc("banana")' -T '{join(extras, " ")}\n' + *useful=b-for-banana* (glob) diff -r a567e5e90b4f -r 144a5814f1ce tests/test-evolve-issue6246.t --- a/tests/test-evolve-issue6246.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-evolve-issue6246.t Wed Oct 18 16:37:08 2023 -0300 @@ -17,7 +17,7 @@ $ touch .hg/cache/evoext_stablerange_v2.sqlite $ chmod 0000 .hg/cache/evoext_stablerange_v2.sqlite - $ hg debugstablerange --method default --verify --subranges --rev 1 --debug + $ hg debug::evo-ext-stable-range --method default --verify --subranges --rev 1 --debug stable-range cache: unable to load, regenerating 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - diff -r a567e5e90b4f -r 144a5814f1ce tests/test-evolve-serveronly-bundle2.t --- a/tests/test-evolve-serveronly-bundle2.t Wed Aug 16 15:11:43 2023 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ - - $ . ${TESTDIR}/testlib/pythonpath.sh - - $ cat >> $HGRCPATH < [web] - > push_ssl = false - > allow_push = * - > [ui] - > ssh = "$PYTHON" "$RUNTESTDIR/dummyssh" - > [phases] - > publish = False - > [experimental] - > bundle2-exp=True - > EOF - - $ mkcommit() { - > echo "$1" > "$1" - > hg add "$1" - > hg ci -m "add $1" - > } - - $ hg init server - -Try the multiple ways to setup the extension - - $ hg -R server log --config 'extensions.evolve.serveronly=' - $ hg -R server log --config "extensions.evolve.serveronly=${SRCDIR}/hgext3rd/evolve/serveronly.py" - $ PYTHONPATH=$HGTEST_ORIG_PYTHONPATH hg -R server log --config "extensions.evolve.serveronly=${SRCDIR}/hgext3rd/evolve/serveronly.py" - -setup repo - - $ echo "[extensions]" >> ./server/.hg/hgrc - $ echo "evolve.serveronly=" >> ./server/.hg/hgrc - $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log - $ cat hg.pid >> $DAEMON_PIDS - - $ hg clone http://localhost:$HGPORT/ client - no changes found - updating to branch default - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cat ./errors.log - $ echo "[extensions]" >> ./client/.hg/hgrc - $ echo "evolve=" >> ./client/.hg/hgrc - $ echo "[paths]" >> ./client/.hg/hgrc - $ echo "ssh=ssh://user@dummy/server/" >> ./client/.hg/hgrc - $ cp -r client other - -Smoke testing -=============== - - $ cd client - $ mkcommit 0 - $ mkcommit a - $ hg push - pushing to http://localhost:$HGPORT/ - searching for changes - remote: adding changesets - remote: adding manifests - remote: adding file changes - remote: added 2 changesets with 2 changes to 2 files - $ hg pull - pulling from http://localhost:$HGPORT/ - searching for changes - no changes found - $ cat ../errors.log - $ hg pull -R ../other - pulling from http://localhost:$HGPORT/ - requesting all changes - adding changesets - adding manifests - adding file changes - added 2 changesets with 2 changes to 2 files - new changesets 8685c6d34325:4957bfdac07e (2 drafts) - (run 'hg update' to get a working copy) - $ cat ../errors.log - $ hg push -R ../other - pushing to http://localhost:$HGPORT/ - searching for changes - no changes found - [1] - $ cat ../errors.log - -Capacity testing -=================== - - $ hg debugdownload http://localhost:$HGPORT/?cmd=hello - capabilities: _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch * (glob) - $ hg debugdownload http://localhost:$HGPORT/?cmd=capabilities - _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch * (glob) - - $ hg debugpushkey http://localhost:$HGPORT namespaces - bookmarks - namespaces - obsolete - phases - -Push -============= - - $ echo 'A' > a - $ hg amend - $ hg push - pushing to http://localhost:$HGPORT/ - searching for changes - remote: adding changesets - remote: adding manifests - remote: adding file changes - remote: added 1 changesets with 1 changes to 1 files (+1 heads) - remote: 1 new obsolescence markers - remote: obsoleted 1 changesets - $ cat ../errors.log - $ hg push - pushing to http://localhost:$HGPORT/ - searching for changes - no changes found - [1] - $ cat ../errors.log - -Pull -============= - - $ hg -R ../other pull - pulling from http://localhost:$HGPORT/ - searching for changes - adding changesets - adding manifests - adding file changes - added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re) - 1 new obsolescence markers - obsoleted 1 changesets - new changesets 9d1c114e7797 (1 drafts) - (run 'hg heads' to see heads) - $ cat ../errors.log - $ hg -R ../other pull - pulling from http://localhost:$HGPORT/ - searching for changes - no changes found - $ cat ../errors.log - - $ cd .. - -Test disabling obsolete advertisement -=========================================== -(used by bitbucket to select which repo use evolve) - - $ hg debugpushkey http://localhost:$HGPORT namespaces - bookmarks - namespaces - obsolete - phases - $ hg debugdownload http://localhost:$HGPORT/?cmd=hello - capabilities: _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch * (glob) - $ hg debugdownload http://localhost:$HGPORT/?cmd=capabilities - _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch * (glob) - - $ echo '[experimental]' >> server/.hg/hgrc - $ echo 'evolution=!' >> server/.hg/hgrc - $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS - $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log - $ cat hg.pid >> $DAEMON_PIDS - - $ hg debugpushkey http://localhost:$HGPORT namespaces - bookmarks - namespaces - phases - - $ echo 'evolution=all' >> server/.hg/hgrc - $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS - $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log - $ cat hg.pid >> $DAEMON_PIDS - - $ hg debugpushkey http://localhost:$HGPORT namespaces - bookmarks - namespaces - obsolete - phases - - $ hg debugdownload http://localhost:$HGPORT/?cmd=hello - capabilities: _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch * (glob) - $ hg debugdownload http://localhost:$HGPORT/?cmd=capabilities - _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch * (glob) - -Test obshashrange discover -=========================================== - - $ cat >> $HGRCPATH < [experimental] - > obshashrange = True - > EOF - $ cd client - $ hg pull ssh - pulling from ssh://user@dummy/server/ - searching for changes - no changes found diff -r a567e5e90b4f -r 144a5814f1ce tests/test-evolve-serveronly-legacy.t --- a/tests/test-evolve-serveronly-legacy.t Wed Aug 16 15:11:43 2023 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ - - $ . ${TESTDIR}/testlib/pythonpath.sh - - $ cat >> $HGRCPATH < [web] - > push_ssl = false - > allow_push = * - > [phases] - > publish = False - > [experimental] - > bundle2-exp=False # < Mercurial-4.0 - > [devel] - > legacy.exchange=bundle1 - > EOF - - $ mkcommit() { - > echo "$1" > "$1" - > hg add "$1" - > hg ci -m "add $1" - > } - - - $ hg init server - -Try the multiple ways to setup the extension - - $ hg -R server log --config 'extensions.evolve.serveronly=' - $ hg -R server log --config "extensions.evolve.serveronly=${SRCDIR}/hgext3rd/evolve/serveronly.py" - $ PYTHONPATH=$HGTEST_ORIG_PYTHONPATH hg -R server log --config "extensions.evolve.serveronly=${SRCDIR}/hgext3rd/evolve/serveronly.py" - -setup repo - - $ echo "[extensions]" >> ./server/.hg/hgrc - $ echo "evolve.serveronly=" >> ./server/.hg/hgrc - $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log --traceback - $ cat hg.pid >> $DAEMON_PIDS - - $ hg clone http://localhost:$HGPORT/ client - no changes found - updating to branch default - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cat ./errors.log - $ echo "[extensions]" >> ./client/.hg/hgrc - $ echo "evolve=" >> ./client/.hg/hgrc - $ cp -r client other - -Smoke testing -=============== - - $ cd client - $ mkcommit 0 - $ mkcommit a - $ hg push - pushing to http://localhost:$HGPORT/ - searching for changes - abort: remote error: - incompatible Mercurial client; bundle2 required - (see https://www.mercurial-scm.org/wiki/IncompatibleClient) - [100] - $ cat ../errors.log diff -r a567e5e90b4f -r 144a5814f1ce tests/test-extension-isolation.t --- a/tests/test-extension-isolation.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-extension-isolation.t Wed Oct 18 16:37:08 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 a567e5e90b4f -r 144a5814f1ce tests/test-minitopic.t --- a/tests/test-minitopic.t Wed Aug 16 15:11:43 2023 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,240 +0,0 @@ - $ . $TESTDIR/testlib/common.sh - -setup - $ cat >> $HGRCPATH << EOF - > [extensions] - > share= - > blackbox= - > [web] - > allow_push = * - > push_ssl = no - > [phases] - > publish = False - > [paths] - > enabled = http://localhost:$HGPORT/ - > disabled = http://localhost:$HGPORT2/ - > EOF - - $ hg init ./server-enabled - $ cat >> server-enabled/.hg/hgrc << EOF - > [extensions] - > serverminitopic= - > [experimental] - > server-mini-topic = yes - > EOF - - $ hg share ./server-enabled ./server-disabled - updating working directory - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cat >> server-disabled/.hg/hgrc << EOF - > [extensions] - > serverminitopic= - > [experimental] - > server-mini-topic = no - > EOF - - $ hg init client-disabled - $ hg init client-enabled - $ cat >> client-enabled/.hg/hgrc << EOF - > [extensions] - > topic= - > EOF - - $ hg serve -R server-enabled -p $HGPORT -d --pid-file hg1.pid --errorlog hg1.error - $ cat hg1.pid > $DAEMON_PIDS - $ hg serve -R server-disabled -p $HGPORT2 -d --pid-file hg2.pid --errorlog hg2.error - $ cat hg2.pid >> $DAEMON_PIDS - - $ hg debugdownload http://localhost:$HGPORT/?cmd=capabilities | grep -o topics - topics - $ hg debugdownload http://localhost:$HGPORT2/?cmd=capabilities | grep -o topics - [1] - -Pushing first changesets to the servers --------------------------------------- - - $ cd client-enabled - $ mkcommit c_A0 - $ hg push enabled - pushing to http://localhost:$HGPORT/ - searching for changes - remote: adding changesets - remote: adding manifests - remote: adding file changes - remote: added 1 changesets with 1 changes to 1 files - $ mkcommit c_B0 - $ hg push disabled - pushing to http://localhost:$HGPORT2/ - searching for changes - remote: adding changesets - remote: adding manifests - remote: adding file changes - remote: added 1 changesets with 1 changes to 1 files - - $ cat $TESTTMP/hg1.error - $ cat $TESTTMP/hg2.error - -Pushing new head ----------------- - - $ hg up 'desc("c_A0")' - 0 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ mkcommit c_C0 - created new head - (consider using topic for lightweight branches. See 'hg help topic') - $ hg push enabled - pushing to http://localhost:$HGPORT/ - searching for changes - abort: push creates new remote head 22c9514ed811 - (merge or see 'hg help push' for details about pushing new heads) - [20] - $ hg push disabled - pushing to http://localhost:$HGPORT2/ - searching for changes - abort: push creates new remote head 22c9514ed811 - (merge or see 'hg help push' for details about pushing new heads) - [20] - - $ hg debugdownload http://localhost:$HGPORT/?cmd=branchmap | sort - default 0ab6d544d0efd629fda056601cfe95e73d1af210 - $ hg debugdownload http://localhost:$HGPORT2/?cmd=branchmap | sort - default 0ab6d544d0efd629fda056601cfe95e73d1af210 - $ cat $TESTTMP/hg1.error - $ cat $TESTTMP/hg2.error - -Pushing new topic ------------------ - - $ hg merge - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - (branch merge, don't forget to commit) - $ mkcommit c_D0 - $ hg log -G - @ changeset: 3:9c660cf97499 - |\ tag: tip - | | parent: 2:22c9514ed811 - | | parent: 1:0ab6d544d0ef - | | user: test - | | date: Thu Jan 01 00:00:00 1970 +0000 - | | summary: c_D0 - | | - | o changeset: 2:22c9514ed811 - | | parent: 0:14faebcf9752 - | | user: test - | | date: Thu Jan 01 00:00:00 1970 +0000 - | | summary: c_C0 - | | - o | changeset: 1:0ab6d544d0ef - |/ user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: c_B0 - | - o changeset: 0:14faebcf9752 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: c_A0 - - $ hg push enabled - pushing to http://localhost:$HGPORT/ - searching for changes - remote: adding changesets - remote: adding manifests - remote: adding file changes - remote: added 2 changesets with 2 changes to 2 files - $ hg up 'desc("c_C0")' - 0 files updated, 0 files merged, 2 files removed, 0 files unresolved - $ hg topic topic_A - marked working directory as topic: topic_A - $ mkcommit c_E0 - active topic 'topic_A' grew its first changeset - (see 'hg help topics' for more information) - $ hg push disabled - pushing to http://localhost:$HGPORT2/ - searching for changes - abort: push creates new remote head f31af349535e - (merge or see 'hg help push' for details about pushing new heads) - [20] - $ hg push enabled - pushing to http://localhost:$HGPORT/ - searching for changes - remote: adding changesets - remote: adding manifests - remote: adding file changes - remote: added 1 changesets with 1 changes to 1 files (+1 heads) - - $ hg debugdownload http://localhost:$HGPORT/?cmd=branchmap | sort - default 9c660cf97499ae01ccb6894880455c6ffa4b19cf - default%3Atopic_A f31af349535e413b6023f11b51a6afccf4139180 - $ hg debugdownload http://localhost:$HGPORT2/?cmd=branchmap | sort - default 9c660cf97499ae01ccb6894880455c6ffa4b19cf f31af349535e413b6023f11b51a6afccf4139180 - $ cat $TESTTMP/hg1.error - $ cat $TESTTMP/hg2.error - -Pushing new head to a topic ---------------------------- - - $ hg up 'desc("c_D0")' - 2 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ hg topic topic_A - marked working directory as topic: topic_A - $ mkcommit c_F0 - $ hg log -G - @ changeset: 5:82c5842e0472 - | tag: tip - | topic: topic_A - | parent: 3:9c660cf97499 - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: c_F0 - | - | o changeset: 4:f31af349535e - | | topic: topic_A - | | parent: 2:22c9514ed811 - | | user: test - | | date: Thu Jan 01 00:00:00 1970 +0000 - | | summary: c_E0 - | | - o | changeset: 3:9c660cf97499 - |\| parent: 2:22c9514ed811 - | | parent: 1:0ab6d544d0ef - | | user: test - | | date: Thu Jan 01 00:00:00 1970 +0000 - | | summary: c_D0 - | | - | o changeset: 2:22c9514ed811 - | | parent: 0:14faebcf9752 - | | user: test - | | date: Thu Jan 01 00:00:00 1970 +0000 - | | summary: c_C0 - | | - o | changeset: 1:0ab6d544d0ef - |/ user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: c_B0 - | - o changeset: 0:14faebcf9752 - user: test - date: Thu Jan 01 00:00:00 1970 +0000 - summary: c_A0 - - $ hg push enabled - pushing to http://localhost:$HGPORT/ - searching for changes - abort: push creates new remote head 82c5842e0472 on branch 'default//topic_A' - (merge or see 'hg help push' for details about pushing new heads) - [20] - $ hg push disabled - pushing to http://localhost:$HGPORT2/ - searching for changes - remote: adding changesets - remote: adding manifests - remote: adding file changes - remote: added 1 changesets with 1 changes to 1 files - - $ hg debugdownload http://localhost:$HGPORT/?cmd=branchmap | sort - default 9c660cf97499ae01ccb6894880455c6ffa4b19cf - default%3Atopic_A f31af349535e413b6023f11b51a6afccf4139180 82c5842e047215160763f81ae93ae42c65b20a63 - $ hg debugdownload http://localhost:$HGPORT2/?cmd=branchmap | sort - default f31af349535e413b6023f11b51a6afccf4139180 82c5842e047215160763f81ae93ae42c65b20a63 - $ cat $TESTTMP/hg1.error - $ cat $TESTTMP/hg2.error diff -r a567e5e90b4f -r 144a5814f1ce tests/test-namespaces-exchange.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-namespaces-exchange.t Wed Oct 18 16:37:08 2023 -0300 @@ -0,0 +1,248 @@ +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 + > [ui] + > logtemplate = "{rev}: {desc} {fqbn} ({phase})\n" + > 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 incoming -R ../clone + comparing with * (glob) + 0: apple default//apple (draft) + + $ 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 incoming -R ../clone --config experimental.tns-default-pull-namespaces=foo + comparing with * (glob) + searching for changes + no changes found + [1] + + $ 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 incoming -R ../clone --config experimental.tns-default-pull-namespaces=foo,bob + comparing with * (glob) + searching for changes + 1: banana default//bob/banana (draft) + + $ 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 incoming -R ../clone --config experimental.tns-default-pull-namespaces=* + comparing with * (glob) + searching for changes + 2: coconut default//charlie/coconut (draft) + + $ 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 incoming -R ../clone + comparing with * (glob) + searching for changes + 3: durian default//dave/durian (draft) + + $ 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) + +testing related config options +also specifying changesets and branches explicitly + + $ echo elderberry > e + $ hg debug-topic-namespace eve + $ hg topic elderberry + $ hg ci -qAm 'elderberry' + + $ echo feijoa > f + $ hg debug-topic-namespace frank + $ hg topic feijoa + $ hg ci -qAm 'feijoa' + +global hgrc + + $ cat >> $HGRCPATH << EOF + > [experimental] + > tns-default-pull-namespaces = alice, bob, eve + > EOF + + $ hg incoming -R ../clone + comparing with * (glob) + searching for changes + 4: elderberry default//eve/elderberry (draft) + +global hgrc with explicit target + + $ hg incoming -R ../clone --rev tip + comparing with * (glob) + searching for changes + 4: elderberry default//eve/elderberry (draft) + 5: feijoa default//frank/feijoa (draft) + +source repo hgrc (should not matter) + + $ cat >> ../orig/.hg/hgrc << EOF + > [experimental] + > tns-default-pull-namespaces = does, not, matter + > EOF + + $ hg incoming -R ../clone + comparing with * (glob) + searching for changes + 4: elderberry default//eve/elderberry (draft) + +local repo hgrc (overrides global hgrc) + + $ cat >> ../clone/.hg/hgrc << EOF + > [experimental] + > tns-default-pull-namespaces = frank + > EOF + + $ hg incoming -R ../clone + comparing with * (glob) + searching for changes + 4: elderberry default//eve/elderberry (draft) + 5: feijoa default//frank/feijoa (draft) + +local repo hgrc with explicit target + + $ hg incoming -R ../clone --rev 4 + comparing with * (glob) + searching for changes + 4: elderberry default//eve/elderberry (draft) + +#if http + $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS + $ cat $TESTTMP/errors.log +#endif + + $ hg branches + default//frank/feijoa 5:c58726fdcfd8 + default//eve/elderberry 4:59694f5082fe (inactive) + default//dave/durian 3:d5d5dda52b2f (inactive) + default//charlie/coconut 2:16d2440597e2 (inactive) + default//bob/banana 1:ed9751f04a18 (inactive) + default//apple 0:bf4c1d971543 (inactive) + + $ cd .. diff -r a567e5e90b4f -r 144a5814f1ce tests/test-namespaces-precheck.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-namespaces-precheck.t Wed Oct 18 16:37:08 2023 -0300 @@ -0,0 +1,96 @@ +Checking affected topic namespaces before history rewrites +========================================================== + + $ . "$TESTDIR/testlib/common.sh" + + $ cat >> $HGRCPATH << EOF + > [extensions] + > evolve = + > topic = + > rebase = + > histedit = + > [phases] + > publish = no + > [experimental] + > tns-allow-rewrite = + > EOF + + $ hg init repo + $ cd repo + +Make sure general checks in precheck() happen before topic namespaces checks + + $ hg prune null + abort: cannot prune the null revision + (no changeset checked out) + [10] + + $ echo apple > a + $ hg ci -qAm apple + + $ hg debug-topic-namespace foo + marked working directory as topic namespace: foo + $ hg topic bar + marked working directory as topic: bar + $ echo banana > b + $ hg ci -qAm 'banana' + +Allowing topic namespaces with --config works correctly + + $ echo broccoli > b + $ hg amend -m 'broccoli' + abort: refusing to amend changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg amend -m 'broccoli' --config experimental.tns-allow-rewrite=foo,something-unrelated + + $ echo coconut > b + $ hg ci -qAm 'coconut' + +Testing history-rewriting commands from evolve extension + + $ hg amend -m 'coconut' + abort: refusing to amend changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg amend --patch -m 'coconut' + abort: refusing to amend changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg uncommit + abort: refusing to uncommit changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg prune -r . + abort: refusing to prune changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg split -r . + abort: refusing to split changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg touch -r . + abort: refusing to touch changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + +Testing core history-rewriting commands + + $ hg ci --amend + abort: refusing to amend changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg branch different-branch --rev . + abort: refusing to change branch of changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg rebase -r . -d null + abort: refusing to rebase changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + $ hg histedit + abort: refusing to edit changesets with these topic namespaces: foo + (modify experimental.tns-allow-rewrite to allow rewriting changesets from these topic namespaces) + [10] + + $ cd .. diff -r a567e5e90b4f -r 144a5814f1ce tests/test-namespaces-report.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-namespaces-report.t Wed Oct 18 16:37:08 2023 -0300 @@ -0,0 +1,284 @@ +============================================================ +Test detection of topic name space affected by a transaction +============================================================ + +Reporting affected topic namespaces in transactions + + $ . "$TESTDIR/testlib/common.sh" + + $ cat >> $HGRCPATH << EOF + > [extensions] + > evolve = + > topic = + > [phases] + > publish = no + > [devel] + > tns-report-transactions = push + > EOF + + $ hg init orig + +case 1: new changeset (draft with topic namespace) +================================================== + +topic namespace of that changeset is reported + + $ hg clone orig case-1 -q + $ cd orig + + $ echo apple > a + $ hg ci -qAm apple + + $ hg push ../case-1 + pushing to ../case-1 + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + + $ echo banana > b + $ hg debug-topic-namespace bob + marked working directory as topic namespace: bob + $ hg topic b + marked working directory as topic: b + $ hg ci -qAm 'banana' + + $ hg push ../case-1 + pushing to ../case-1 + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: bob + added 1 changesets with 1 changes to 1 files + + $ cd .. + +case 2: obsmarker affecting known changeset +=========================================== + +topic namespaces of both the precursor and the successor are affected + + $ hg clone orig case-2 -q + $ cd orig + + $ echo broccoli > b + $ hg debug-topic-namespace bruce + $ hg ci --amend -m 'broccoli' + + $ hg push ../case-2 + pushing to ../case-2 + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: bob bruce + added 1 changesets with 1 changes to 1 files (+1 heads) + 1 new obsolescence markers + obsoleted 1 changesets + + $ cd .. + +case 3: phase divergence +======================== + +3 phase divergence resolution can point to a thing but not affect it (probably not affected) + +In this case, the pushed changeset comes with an obsmarker whose predecessors +has the `charlie` topic-namespace and the successors has the `carol` +topic-namespace. However, that obsolescence is part of a phase-divergence +fixup, so we should now mark `coconut` as affected since it is already public. + + $ hg clone orig case-3 -q + $ cd orig + + $ hg debug-topic-namespace charlie + $ hg topic c + $ echo coconut > c + $ hg ci -qAm 'coconut' + + $ hg debug-topic-namespace carol + $ echo cloudberry > c + $ hg ci --amend -m 'cloudberry' + + $ hg phase --hidden -r 'desc("coconut")' --public + 1 new phase-divergent changesets + + $ hg evolve --phase-divergent + recreate:[s1] cloudberry + atop:[3] coconut + committed as 9f1abc6f4a6f + working directory is now at 9f1abc6f4a6f + + $ hg push ../case-3 + pushing to ../case-3 + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: bruce carol + added 2 changesets with 2 changes to 1 files + 2 new obsolescence markers + + $ cd .. + +case 4: phase movement: publishing drafts +========================================= + +topic namespaces of published changesets are affected + + $ hg clone orig case-4 -q + $ cd orig + + $ hg push ../case-4 --publish + pushing to ../case-4 + searching for changes + no changes found + topic namespaces affected: carol + active topic 'c' is now empty + (use 'hg topic --clear' to clear it if needed) + [1] + + $ cd .. + +case 5: bookmark movement +========================= + +Bookmark movement that affect tns (like putting a bookmark on obsolete +changesets) their topic namespaces reappear and are therefore reported + + $ hg clone orig case-5 -q + $ cd orig + + $ hg debug-topic-namespace dana + $ hg topic d + $ echo durian > d + $ hg ci -qAm 'durian' + + $ hg push ../case-5 + pushing to ../case-5 + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: dana + added 1 changesets with 1 changes to 1 files + + $ hg debug-topic-namespace dave + $ echo dragonfruit > d + $ hg ci --amend -m 'dragonfruit' + + $ hg push ../case-5 + pushing to ../case-5 + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: dana dave + added 1 changesets with 1 changes to 1 files (+1 heads) + 1 new obsolescence markers + obsoleted 1 changesets + + $ hg bookmark --hidden -r 'desc("durian")' @ + bookmarking hidden changeset c56d89b2348b + (hidden revision 'c56d89b2348b' was rewritten as: 7fc662c4767d) + + $ hg push ../case-5 -B @ + pushing to ../case-5 + searching for changes + no changes found + topic namespaces affected: dana + exporting bookmark @ + [1] + + $ cd .. + +case 6: phase movement: publishing secret changesets +==================================================== + +(that are known on the server) + +topic namespaces of published changesets are affected + + $ hg clone orig case-6 -q + $ cd orig + +XXX: we see "active topic is now empty" twice because stack doesn't handle topic namespaces yet + + $ hg push ../case-6 -r . --publish + pushing to ../case-6 + searching for changes + no changes found + topic namespaces affected: dave + active topic 'd' is now empty + active topic 'd' is now empty + (use 'hg topic --clear' to clear it if needed) + [1] + +previous topic namespace is resurrected... + + $ hg phase --secret --force -r . --config 'devel.tns-report-transactions=phase' + topic namespaces affected: dave + active topic 'd' grew its first changeset + (see 'hg help topics' for more information) + +...just to disappear again + + $ hg push ../case-6 -r . --config 'devel.tns-report-transactions=*' + pushing to ../case-6 + searching for changes + no changes found + topic namespaces affected: dave + active topic 'd' is now empty + (use 'hg topic --clear' to clear it if needed) + [1] + + $ cd .. + +case 7: phase movement: secret->draft on the server +=================================================== + +changeset becomes visible to peers, so its topic namespace is affected + + $ hg clone orig case-7 -q + $ cd orig + + $ hg phase --draft --force -r tip + active topic 'd' grew its first changeset + (see 'hg help topics' for more information) + $ hg phase --secret --force -r tip -R ../case-7 + active topic 'd' grew its first changeset + (see 'hg help topics' for more information) + + $ hg push ../case-7 -r . --config 'devel.tns-report-transactions=*' + pushing to ../case-7 + searching for changes + adding changesets + adding manifests + adding file changes + topic namespaces affected: dave + added 0 changesets with 0 changes to 1 files + active topic 'd' grew its first changeset + (see 'hg help topics' for more information) + + $ cd .. + +case: 99 pushing obsmarker for an unknown changeset +=================================================== +doesn't affect any topic namespace, we report nothing + + $ hg clone orig case-99 -q + $ cd orig + + $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid "desc('dragonfruit')"` + 1 new obsolescence markers + + $ hg push ../case-99 + pushing to ../case-99 + searching for changes + no changes found + 1 new obsolescence markers + [1] + + $ cd .. diff -r a567e5e90b4f -r 144a5814f1ce tests/test-namespaces.t --- a/tests/test-namespaces.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-namespaces.t Wed Oct 18 16:37:08 2023 -0300 @@ -5,22 +5,40 @@ $ hg init repo $ cd repo +Setting a topic namespace alone doesn't affect wdir() + $ hg debug-topic-namespace space-name marked working directory as topic namespace: space-name $ hg debug-topic-namespaces space-name $ hg log -r 'wdir()' -T '{topic_namespace}\n' + none + + $ hg log -r 'wdir()' -T '{fqbn}\n' + default + +But after setting a topic the already-set namespace is visible on wdir() + + $ hg topic feature + marked working directory as topic: feature + $ hg topics + * feature (0 changesets) + + $ hg log -r 'wdir()' -T '{topic_namespace}\n' space-name $ hg log -r 'wdir()' -T '{fqbn}\n' - default//space-name/ + default//space-name/feature $ hg branches $ hg debug-topic-namespace --clear $ hg debug-topic-namespaces - default + + $ hg topic --clear + clearing empty topic "feature" + $ hg topics $ hg debugtopicnamespace --clear nonsense abort: cannot use --clear when setting a topic namespace @@ -53,7 +71,7 @@ $ hg up null 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg debug-topic-namespace - default + none $ hg topics feature (1 changesets) $ hg up 0 @@ -81,6 +99,7 @@ # Branch stable # Node ID 69c7dbf6acd180eeec055dd67933badd3601d45f # Parent 0000000000000000000000000000000000000000 + # EXP-Topic-Namespace alice # EXP-Topic feature a @@ -96,8 +115,9 @@ > # Date 0 0 > # Thu Jan 01 00:00:00 1970 +0000 > # Branch another-branch - > # Node ID 94981e5d988ea23cf2b17f6c07c39edc0f174b01 - > # Parent d6d47657e765570283ec03fc68836d9eb297c4b3 + > # Node ID 1111111111111111111111111111111111111111 + > # Parent 2222222222222222222222222222222222222222 + > # EXP-Topic-Namespace mynamespace > # EXP-Topic mytopic > added z > @@ -111,10 +131,77 @@ applying patch from stdin $ hg log -r tip -T '{rev}: {branch} {topic_namespace} {topic}\n' - 1: stable alice mytopic + 1: stable mynamespace mytopic + + $ hg log -r tip -T '{rev}: {fqbn}\n' + 1: stable//mynamespace/mytopic + + $ hg log -r tip -T '{rev}: {join(extras, " ")}\n' + 1: branch=stable topic=mytopic topic-namespace=mynamespace + +Importing a patch with default namespace and topic values + + $ hg import - << EOF + > # HG changeset patch + > # User test + > # Date 0 0 + > # Thu Jan 01 00:00:00 1970 +0000 + > # Branch stable + > # Node ID 1111111111111111111111111111111111111111 + > # Parent 2222222222222222222222222222222222222222 + > # EXP-Topic-Namespace none + > # EXP-Topic + > more z + > + > diff --git a/z b/z + > --- a/z + > +++ b/z + > @@ -1,1 +1,1 @@ + > -z + > +zebra + > EOF + applying patch from stdin + + $ hg log -r tip -T '{rev}: {branch} {topic_namespace} {topic}\n' + 2: stable none $ hg log -r tip -T '{rev}: {fqbn}\n' - 1: stable//alice/mytopic + 2: stable + + $ hg log -r tip -T '{rev}: {join(extras, " ")}\n' + 2: branch=stable + +Importing a patch with topic namespace set and topic unset + + $ hg import - << EOF + > # HG changeset patch + > # User test + > # Date 0 0 + > # Thu Jan 01 00:00:00 1970 +0000 + > # Branch stable + > # Node ID 1111111111111111111111111111111111111111 + > # Parent 2222222222222222222222222222222222222222 + > # EXP-Topic-Namespace mynamespace + > # EXP-Topic + > more z + > + > diff --git a/z b/z + > --- a/z + > +++ b/z + > @@ -1,1 +1,1 @@ + > -zebra + > +z + > EOF + applying patch from stdin + + $ hg log -r tip -T '{rev}: {branch} {topic_namespace} {topic}\n' + 3: stable none + + $ hg log -r tip -T '{rev}: {fqbn}\n' + 3: stable + + $ hg log -r tip -T '{rev}: {join(extras, " ")}\n' + 3: branch=stable Revsets @@ -122,21 +209,21 @@ > hg log -T '{rev}: {topic_namespace}\n' -r "$1" > } + $ nslog 'topicnamespace()' + 0: alice + 1: mynamespace $ nslog 'topicnamespace(:)' 0: alice - 1: alice + 1: mynamespace $ nslog 'topicnamespace(all())' 0: alice - 1: alice + 1: mynamespace $ nslog 'topicnamespace(topicnamespace("alice"))' 0: alice - 1: alice $ nslog 'topicnamespace(wdir())' 0: alice - 1: alice $ nslog 'topicnamespace("re:ice$")' 0: alice - 1: alice $ nslog 'topicnamespace(nonsense)' abort: unknown revision 'nonsense' [10] @@ -154,7 +241,7 @@ no double slashes means it's a named branch $ hg debug-parse-fqbn foo/bar branch: foo/bar - namespace: default + namespace: none topic: Formatting @@ -170,9 +257,9 @@ default values - $ hg debug-format-fqbn -b default -n default -t '' --no-short - default//default/ - $ hg debug-format-fqbn -b default -n default -t '' --short + $ hg debug-format-fqbn -b default -n none -t '' --no-short + default//none/ + $ hg debug-format-fqbn -b default -n none -t '' --short default $ hg debug-format-fqbn -b default -n namespace -t '' --no-short @@ -180,9 +267,9 @@ $ hg debug-format-fqbn -b default -n namespace -t '' --short default//namespace/ - $ hg debug-format-fqbn -b default -n default -t topic --no-short - default//default/topic - $ hg debug-format-fqbn -b default -n default -t topic --short + $ hg debug-format-fqbn -b default -n none -t topic --no-short + default//none/topic + $ hg debug-format-fqbn -b default -n none -t topic --short default//topic $ cd .. diff -r a567e5e90b4f -r 144a5814f1ce tests/test-pick.t --- a/tests/test-pick.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-pick.t Wed Oct 18 16:37:08 2023 -0300 @@ -380,6 +380,41 @@ $ hg phase -r . 13: secret + +Pick rewrites node hashes in commit description + + $ echo 'hg pick rewrites hashes 1' > l + $ hg ci -m '1705aa17bfed is my parent' + $ echo 'hg pick rewrites hashes 2' > l + $ hg ci -m 'f9ed1703aa00 is my parent' + + $ hg glog -r .^^:: + @ 15:e3cb66090723 f9ed1703aa00 is my parent + | + o 14:f9ed1703aa00 1705aa17bfed is my parent + | + o 13:1705aa17bfed added l + | + ~ + + $ hg up -q c437988de89f + $ hg pick 13 + picking 13:1705aa17bfed "added l" + 2 new orphan changesets + $ hg pick 14 + picking 14:f9ed1703aa00 "1705aa17bfed is my parent" + $ hg pick 15 + picking 15:e3cb66090723 "f9ed1703aa00 is my parent" + + $ hg glog -r .^^:: + @ 18:5825531d1322 7a6997f82fbe is my parent + | + o 17:7a6997f82fbe fb6281ea03e8 is my parent + | + o 16:fb6281ea03e8 added l + | + ~ + $ cd .. Check pick behavior regarding working copy branch (issue6089) diff -r a567e5e90b4f -r 144a5814f1ce tests/test-split.t --- a/tests/test-split.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-split.t Wed Oct 18 16:37:08 2023 -0300 @@ -543,6 +543,7 @@ # Branch another-branch # Node ID 94981e5d988ea23cf2b17f6c07c39edc0f174b01 # Parent d6d47657e765570283ec03fc68836d9eb297c4b3 + # EXP-Topic-Namespace mynamespace # EXP-Topic mytopic To be split @@ -739,6 +740,7 @@ # Branch another-branch # Node ID 61661257a93759374255a4c05fcd9b8a78bbe399 # Parent a05395d0b42120af8bfb222d19f01008b1342c15 + # EXP-Topic-Namespace mynamespace # EXP-Topic mytopic split10 @@ -755,6 +757,7 @@ # Branch another-branch # Node ID e6ca7ba1372dc452769c51a56d853c8ede26d9fa # Parent a05395d0b42120af8bfb222d19f01008b1342c15 + # EXP-Topic-Namespace mynamespace # EXP-Topic mytopic split10 @@ -791,6 +794,7 @@ # Branch another-branch # Node ID bb8f1c282ddf89515bd07bd63a84962ab51ac277 # Parent a05395d0b42120af8bfb222d19f01008b1342c15 + # EXP-Topic-Namespace mynamespace # EXP-Topic mytopic split12 diff -r a567e5e90b4f -r 144a5814f1ce tests/test-stablerange-branchpoint.t --- a/tests/test-stablerange-branchpoint.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-stablerange-branchpoint.t Wed Oct 18 16:37:08 2023 -0300 @@ -15,14 +15,14 @@ #if basic-branchpoint $ cat << EOF >> $HGRCPATH > [defaults] - > debugstablerange = --method basic-branchpoint + > debug::evo-ext-stable-range = --method basic-branchpoint > EOF #endif #if branchpoint $ cat << EOF >> $HGRCPATH > [defaults] - > debugstablerange = --method branchpoint + > debug::evo-ext-stable-range = --method branchpoint > EOF #endif @@ -40,14 +40,14 @@ bebd167eb94d 5 c8d03c1b5e94 6 f69452c5b1af 7 - $ hg debugstablerange --verify --verbose --subranges --rev 1 | tee 1.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 1 | tee 1.range 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - 66f7d451a68b-1 (1, 2, 1) [leaf] - bigger subset reuse most of the previous one - $ hg debugstablerange --verify --verbose --subranges --rev 4 | tee 4.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 4 | tee 4.range bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) @@ -75,7 +75,7 @@ Using a range not ending on 2**N boundary we fall back on 2**N as much as possible - $ hg debugstablerange --verify --verbose --subranges --rev 5 | tee 5.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 5 | tee 5.range c8d03c1b5e94-0 (5, 6, 6) [complete] - 2dc09a01254d-0 (3, 4, 4), c8d03c1b5e94-4 (5, 6, 2) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) @@ -107,7 +107,7 @@ Even two unperfect range overlap a lot - $ hg debugstablerange --verify --verbose --subranges --rev tip | tee tip.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev tip | tee tip.range f69452c5b1af-0 (6, 7, 7) [complete] - 2dc09a01254d-0 (3, 4, 4), f69452c5b1af-4 (6, 7, 3) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) f69452c5b1af-4 (6, 7, 3) [complete] - c8d03c1b5e94-4 (5, 6, 2), f69452c5b1af-6 (6, 7, 1) @@ -192,11 +192,11 @@ (left branch) - $ hg debugstablerange --verify --verbose --subranges --rev 'left~2' | tee left-2.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 'left~2' | tee left-2.range 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - 66f7d451a68b-1 (1, 2, 1) [leaf] - - $ hg debugstablerange --verify --verbose --subranges --rev left | tee left.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev left | tee left.range 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) @@ -219,11 +219,11 @@ (right branch) - $ hg debugstablerange --verify --verbose --subranges --rev right~2 | tee right-2.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev right~2 | tee right-2.range e7bd5218ca15-0 (4, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), e7bd5218ca15-1 (4, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - e7bd5218ca15-1 (4, 2, 1) [leaf] - - $ hg debugstablerange --verify --verbose --subranges --rev right | tee right.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev right | tee right.range a2f58e9c1e56-0 (6, 4, 4) [complete] - e7bd5218ca15-0 (4, 2, 2), a2f58e9c1e56-2 (6, 4, 2) a2f58e9c1e56-2 (6, 4, 2) [complete] - 3a367db1fabc-2 (5, 3, 1), a2f58e9c1e56-3 (6, 4, 1) e7bd5218ca15-0 (4, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), e7bd5218ca15-1 (4, 2, 1) @@ -246,7 +246,7 @@ The merge reuse as much of the slicing created for one of the branch - $ hg debugstablerange --verify --verbose --subranges --rev merge | tee merge.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev merge | tee merge.range 5f18015f9110-0 (7, 8, 8) [complete] - 2dc09a01254d-0 (3, 4, 4), 5f18015f9110-4 (7, 8, 4) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 5f18015f9110-4 (7, 8, 4) [complete] - 3a367db1fabc-1 (5, 3, 2), 5f18015f9110-6 (7, 8, 2) @@ -372,13 +372,13 @@ (left branch) - $ hg debugstablerange --verify --verbose --subranges --rev 'left~2' | tee left-2.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 'left~2' | tee left-2.range 01241442b3c2-0 (2, 3, 3) [complete] - 66f7d451a68b-0 (1, 2, 2), 01241442b3c2-2 (2, 3, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) 01241442b3c2-2 (2, 3, 1) [leaf] - 1ea73414a91b-0 (0, 1, 1) [leaf] - 66f7d451a68b-1 (1, 2, 1) [leaf] - - $ hg debugstablerange --verify --verbose --subranges --rev left | tee left.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev left | tee left.range bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) @@ -406,7 +406,7 @@ (right branch) - $ hg debugstablerange --verify --verbose --subranges --rev right~2 | tee right-2.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev right~2 | tee right-2.range 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) @@ -414,7 +414,7 @@ 42b07e8da27d-3 (7, 4, 1) [leaf] - b9bc20507e0b-2 (6, 3, 1) [leaf] - de561312eff4-1 (5, 2, 1) [leaf] - - $ hg debugstablerange --verify --verbose --subranges --rev right | tee right.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev right | tee right.range f4b7da68b467-0 (9, 6, 6) [complete] - 42b07e8da27d-0 (7, 4, 4), f4b7da68b467-4 (9, 6, 2) 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) @@ -449,7 +449,7 @@ We are still able to reuse one of the branch however - $ hg debugstablerange --verify --verbose --subranges --rev merge | tee merge.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev merge | tee merge.range 8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) @@ -526,7 +526,7 @@ Range above the merge, reuse subrange from the merge - $ hg debugstablerange --verify --verbose --subranges --rev tip | tee tip.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev tip | tee tip.range e6b8d5b46647-0 (12, 13, 13) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), e6b8d5b46647-8 (12, 13, 5) bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) e6b8d5b46647-8 (12, 13, 5) [complete] - 485383494a89-8 (11, 12, 4), e6b8d5b46647-12 (12, 13, 1) @@ -653,7 +653,7 @@ b4594d867745 6 43227190fef8 5 1d8d22637c2d 8 - $ hg debugstablerange --verify --verbose --subranges --rev 'head()' + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 'head()' 1d8d22637c2d-0 (15, 8, 8) [complete] - 2b6d669947cd-0 (3, 4, 4), 1d8d22637c2d-4 (15, 8, 4) dcbb326fdec2-0 (9, 7, 7) [complete] - 2b6d669947cd-0 (3, 4, 4), dcbb326fdec2-4 (9, 7, 3) ff43616e5d0f-0 (10, 7, 7) [complete] - 2b6d669947cd-0 (3, 4, 4), ff43616e5d0f-4 (10, 7, 3) @@ -718,7 +718,7 @@ fa942426a6fd 2 36315563e2fa 3 f37e476fba9a 5 - $ hg debugstablerange --verify --verbose --subranges --rev 'head()' + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 'head()' f37e476fba9a-0 (4, 5, 5) [complete] - 66f7d451a68b-0 (1, 2, 2), 36315563e2fa-1 (3, 3, 2), f37e476fba9a-4 (4, 5, 1) 36315563e2fa-1 (3, 3, 2) [complete] - fa942426a6fd-1 (2, 2, 1), 36315563e2fa-2 (3, 3, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) diff -r a567e5e90b4f -r 144a5814f1ce tests/test-stablerange.t --- a/tests/test-stablerange.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-stablerange.t Wed Oct 18 16:37:08 2023 -0300 @@ -15,21 +15,21 @@ #if default $ cat << EOF >> $HGRCPATH > [defaults] - > debugstablerange = --method default + > debug::evo-ext-stable-range = --method default > EOF #endif #if basic-mergepoint $ cat << EOF >> $HGRCPATH > [defaults] - > debugstablerange = --method basic-mergepoint + > debug::evo-ext-stable-range = --method basic-mergepoint > EOF #endif #if mergepoint $ cat << EOF >> $HGRCPATH > [defaults] - > debugstablerange = --method mergepoint + > debug::evo-ext-stable-range = --method mergepoint > EOF #endif @@ -47,14 +47,14 @@ bebd167eb94d 5 c8d03c1b5e94 6 f69452c5b1af 7 - $ hg debugstablerange --verify --verbose --subranges --rev 1 | tee 1.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 1 | tee 1.range 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - 66f7d451a68b-1 (1, 2, 1) [leaf] - bigger subset reuse most of the previous one - $ hg debugstablerange --verify --verbose --subranges --rev 4 | tee 4.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 4 | tee 4.range bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) @@ -82,7 +82,7 @@ Using a range not ending on 2**N boundary we fall back on 2**N as much as possible - $ hg debugstablerange --verify --verbose --subranges --rev 5 | tee 5.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 5 | tee 5.range c8d03c1b5e94-0 (5, 6, 6) [complete] - 2dc09a01254d-0 (3, 4, 4), c8d03c1b5e94-4 (5, 6, 2) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) @@ -114,7 +114,7 @@ Even two unperfect range overlap a lot - $ hg debugstablerange --verify --verbose --subranges --rev tip | tee tip.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev tip | tee tip.range f69452c5b1af-0 (6, 7, 7) [complete] - 2dc09a01254d-0 (3, 4, 4), f69452c5b1af-4 (6, 7, 3) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) f69452c5b1af-4 (6, 7, 3) [complete] - c8d03c1b5e94-4 (5, 6, 2), f69452c5b1af-6 (6, 7, 1) @@ -199,11 +199,11 @@ (left branch) - $ hg debugstablerange --verify --verbose --subranges --rev 'left~2' | tee left-2.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 'left~2' | tee left-2.range 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - 66f7d451a68b-1 (1, 2, 1) [leaf] - - $ hg debugstablerange --verify --verbose --subranges --rev left | tee left.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev left | tee left.range 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) @@ -226,11 +226,11 @@ (right branch) - $ hg debugstablerange --verify --verbose --subranges --rev right~2 | tee right-2.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev right~2 | tee right-2.range e7bd5218ca15-0 (4, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), e7bd5218ca15-1 (4, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - e7bd5218ca15-1 (4, 2, 1) [leaf] - - $ hg debugstablerange --verify --verbose --subranges --rev right | tee right.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev right | tee right.range a2f58e9c1e56-0 (6, 4, 4) [complete] - e7bd5218ca15-0 (4, 2, 2), a2f58e9c1e56-2 (6, 4, 2) a2f58e9c1e56-2 (6, 4, 2) [complete] - 3a367db1fabc-2 (5, 3, 1), a2f58e9c1e56-3 (6, 4, 1) e7bd5218ca15-0 (4, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), e7bd5218ca15-1 (4, 2, 1) @@ -253,7 +253,7 @@ The merge reuse as much of the slicing created for one of the branch - $ hg debugstablerange --verify --verbose --subranges --rev merge | tee merge.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev merge | tee merge.range 5f18015f9110-0 (7, 8, 8) [complete] - 2dc09a01254d-0 (3, 4, 4), 5f18015f9110-4 (7, 8, 4) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 5f18015f9110-4 (7, 8, 4) [complete] - 3a367db1fabc-1 (5, 3, 2), 5f18015f9110-6 (7, 8, 2) @@ -379,13 +379,13 @@ (left branch) - $ hg debugstablerange --verify --verbose --subranges --rev 'left~2' | tee left-2.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 'left~2' | tee left-2.range 01241442b3c2-0 (2, 3, 3) [complete] - 66f7d451a68b-0 (1, 2, 2), 01241442b3c2-2 (2, 3, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) 01241442b3c2-2 (2, 3, 1) [leaf] - 1ea73414a91b-0 (0, 1, 1) [leaf] - 66f7d451a68b-1 (1, 2, 1) [leaf] - - $ hg debugstablerange --verify --verbose --subranges --rev left | tee left.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev left | tee left.range bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) @@ -413,7 +413,7 @@ (right branch) - $ hg debugstablerange --verify --verbose --subranges --rev right~2 | tee right-2.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev right~2 | tee right-2.range 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) @@ -421,7 +421,7 @@ 42b07e8da27d-3 (7, 4, 1) [leaf] - b9bc20507e0b-2 (6, 3, 1) [leaf] - de561312eff4-1 (5, 2, 1) [leaf] - - $ hg debugstablerange --verify --verbose --subranges --rev right | tee right.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev right | tee right.range f4b7da68b467-0 (9, 6, 6) [complete] - 42b07e8da27d-0 (7, 4, 4), f4b7da68b467-4 (9, 6, 2) 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) @@ -456,7 +456,7 @@ We are still able to reuse one of the branch however - $ hg debugstablerange --verify --verbose --subranges --rev merge | tee merge.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev merge | tee merge.range 8aca7f8c9bd2-0 (10, 11, 11) [complete] - f4b7da68b467-0 (9, 6, 6), 01241442b3c2-1 (2, 3, 2), 8aca7f8c9bd2-8 (10, 11, 3) f4b7da68b467-0 (9, 6, 6) [complete] - 42b07e8da27d-0 (7, 4, 4), f4b7da68b467-4 (9, 6, 2) 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) @@ -534,7 +534,7 @@ Range above the merge, reuse subrange from the merge - $ hg debugstablerange --verify --verbose --subranges --rev tip | tee tip.range + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev tip | tee tip.range e6b8d5b46647-0 (12, 13, 13) [complete] - f4b7da68b467-0 (9, 6, 6), 01241442b3c2-1 (2, 3, 2), e6b8d5b46647-8 (12, 13, 5) f4b7da68b467-0 (9, 6, 6) [complete] - 42b07e8da27d-0 (7, 4, 4), f4b7da68b467-4 (9, 6, 2) e6b8d5b46647-8 (12, 13, 5) [complete] - 485383494a89-8 (11, 12, 4), e6b8d5b46647-12 (12, 13, 1) @@ -661,7 +661,7 @@ b4594d867745 6 43227190fef8 5 1d8d22637c2d 8 - $ hg debugstablerange --verify --verbose --subranges --rev 'head()' + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 'head()' 1d8d22637c2d-0 (15, 8, 8) [complete] - 2b6d669947cd-0 (3, 4, 4), 1d8d22637c2d-4 (15, 8, 4) dcbb326fdec2-0 (9, 7, 7) [complete] - 2b6d669947cd-0 (3, 4, 4), dcbb326fdec2-4 (9, 7, 3) ff43616e5d0f-0 (10, 7, 7) [complete] - 2b6d669947cd-0 (3, 4, 4), ff43616e5d0f-4 (10, 7, 3) @@ -726,7 +726,7 @@ fa942426a6fd 2 36315563e2fa 3 f37e476fba9a 5 - $ hg debugstablerange --verify --verbose --subranges --rev 'head()' + $ hg debug::evo-ext-stable-range --verify --verbose --subranges --rev 'head()' f37e476fba9a-0 (4, 5, 5) [complete] - 36315563e2fa-0 (3, 3, 3), 66f7d451a68b-1 (1, 2, 1), f37e476fba9a-4 (4, 5, 1) 36315563e2fa-0 (3, 3, 3) [complete] - fa942426a6fd-0 (2, 2, 2), 36315563e2fa-2 (3, 3, 1) fa942426a6fd-0 (2, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), fa942426a6fd-1 (2, 2, 1) diff -r a567e5e90b4f -r 144a5814f1ce tests/test-stablesort-branchpoint-criss-cross.t --- a/tests/test-stablesort-branchpoint-criss-cross.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-stablesort-branchpoint-criss-cross.t Wed Oct 18 16:37:08 2023 -0300 @@ -9,7 +9,7 @@ > [ui] > logtemplate = "{rev} {node|short} {desc} {tags}\n" > [alias] - > showsort = debugstablesort --template="{node|short}\n" --method branchpoint + > showsort = debug::evo-ext-stable-sort --template="{node|short}\n" --method branchpoint > EOF $ checktopo () { diff -r a567e5e90b4f -r 144a5814f1ce tests/test-stablesort-branchpoint.t --- a/tests/test-stablesort-branchpoint.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-stablesort-branchpoint.t Wed Oct 18 16:37:08 2023 -0300 @@ -9,7 +9,7 @@ > [ui] > logtemplate = "{rev} {node|short} {desc} {tags}\n" > [alias] - > showsort = debugstablesort --template="{node|short}\n" --method branchpoint + > showsort = debug::evo-ext-stable-sort --template="{node|short}\n" --method branchpoint > EOF $ checktopo () { diff -r a567e5e90b4f -r 144a5814f1ce tests/test-stablesort-criss-cross.t --- a/tests/test-stablesort-criss-cross.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-stablesort-criss-cross.t Wed Oct 18 16:37:08 2023 -0300 @@ -9,7 +9,7 @@ > [ui] > logtemplate = "{rev} {node|short} {desc} {tags}\n" > [alias] - > showsort = debugstablesort --template="{node|short}\n" --method headondisk + > showsort = debug::evo-ext-stable-sort --template="{node|short}\n" --method headondisk > EOF $ checktopo () { diff -r a567e5e90b4f -r 144a5814f1ce tests/test-stablesort.t --- a/tests/test-stablesort.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-stablesort.t Wed Oct 18 16:37:08 2023 -0300 @@ -9,8 +9,8 @@ > [ui] > logtemplate = "{rev} {node|short} {desc} {tags}\n" > [alias] - > showsort = debugstablesort --template="{node|short}\n" --method basic-mergepoint - > showsorthead = debugstablesort --template="{node|short}\n" --method headondisk + > showsort = debug::evo-ext-stable-sort --template="{node|short}\n" --method basic-mergepoint + > showsorthead = debug::evo-ext-stable-sort --template="{node|short}\n" --method headondisk > EOF $ checktopo () { diff -r a567e5e90b4f -r 144a5814f1ce tests/test-topic-flow-publish-bare.t --- a/tests/test-topic-flow-publish-bare.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-topic-flow-publish-bare.t Wed Oct 18 16:37:08 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 diff -r a567e5e90b4f -r 144a5814f1ce tests/test-topic-stack.t --- a/tests/test-topic-stack.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-topic-stack.t Wed Oct 18 16:37:08 2023 -0300 @@ -676,6 +676,8 @@ $ echo aaa > aaa $ hg commit -Am 'c_A' adding aaa + $ hg debug-topic-namespace my-tns + marked working directory as topic namespace: my-tns $ hg topic red marked working directory as topic: red $ echo bbb > bbb @@ -905,12 +907,13 @@ get things linear again $ hg rebase -r s1 -d default - rebasing 16:1d84ec948370 tip blue "c_D" + rebasing 16:c9b07601c2f4 tip blue "c_D" + switching to topic-namespace my-tns switching to topic blue $ hg rebase -r s2 -d s1 - rebasing 13:3ab2eedae500 blue "c_G" + rebasing 13:90c34d9f99aa blue "c_G" $ hg rebase -r s3 -d s2 - rebasing 8:3bfe800e0486 blue "c_I" + rebasing 8:77174443ad61 blue "c_I" $ hg stack ### topic: blue ### target: default (branch) @@ -967,48 +970,49 @@ continue splitting? [Ycdq?] c $ hg debugobsolete - 34679cfcccdd07565970b959c79428af9a5744e4 6a11ae6b0cde4d4952ed68e8077b9e3596d99548 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} - 20f7945d89a5e372b7548f766ebc800677856443 3c7bec987cd37ba12b83c01683e8609dd549c07b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} - 952e24687ebc5f11743268f6f1c3f24fa83c7ddd 74979543bf1d6c0f75229991400f352a6fb3fddb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} - c9961f97c7b40b54b3c1922986675d6f38793014 d7bfa3d6ce36dfb917547246752f0c2a564fe33b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} - c7d60a180d05255e8c6ea50bce09d014015b7cdc 3ab2eedae500f52b6aa220bb8ce6e20732a8a6d1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} - 6a11ae6b0cde4d4952ed68e8077b9e3596d99548 61700bf67137c724a72aa5f034e9187d2c5e7e47 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} - 3c7bec987cd37ba12b83c01683e8609dd549c07b 4bcfa5dd0945476ba938e8115e81ba367af3b573 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} - 74979543bf1d6c0f75229991400f352a6fb3fddb 1d84ec948370a2ac1a51f3ab27835e31d50c3407 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} - 1d84ec948370a2ac1a51f3ab27835e31d50c3407 f3328cd199dc389b850ca952f65a15a8e6dbc79b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} - 3ab2eedae500f52b6aa220bb8ce6e20732a8a6d1 907f7d3c2333082d62942ac3a47e466ce03d82b9 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} - 3bfe800e04863d23f909f8d98848656b7b5a971a 662ff4ad29901b325a64c39f7850e3efaaeeccc5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} - 907f7d3c2333082d62942ac3a47e466ce03d82b9 b24bab30ac12f6124a52e74aaf46b7468e42526c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'} - b24bab30ac12f6124a52e74aaf46b7468e42526c dde94df880e97f4a1ee8c5408254b429b3d90204 e7ea874afbd5c17aeee366d39a828dbcb01682ce 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'split', 'user': 'test'} + 8da160be12a0d8d40b5aad42aea02123e255f802 6646bdc8cb87942886d4b8548bc243aaacf94b61 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} + 2dc043b3e268bc3d7f30fc2319a72f4430af1d31 6044ea1ba1f7e573bc33312518cd005c45e2ad7d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} + d2c0265139080fe437d3550f5a6c975bc5c3f545 03ec02fb9548883827e62560d0b1e786851f4536 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} + 97cd99629af4d20fc3ccb0989d36294a85dd026d 17318610d72be0981692fb3f02ef1bf30191367e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} + 78da2467366f01b547bd1fc39bcfcc5917be7caa 90c34d9f99aafcc26de07beb0b3c85856de0fa46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} + 6646bdc8cb87942886d4b8548bc243aaacf94b61 3603891aa2fe38371f226d956f39252576155fba 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} + 6044ea1ba1f7e573bc33312518cd005c45e2ad7d 0a3ac1989f8bde7725203cba7a812e547af916fc 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} + 03ec02fb9548883827e62560d0b1e786851f4536 c9b07601c2f4a8c6c0bd8fe292d6d2e85b872d56 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'amend', 'user': 'test'} + c9b07601c2f4a8c6c0bd8fe292d6d2e85b872d56 eed7b08171dd3b5a9359789531abc0bed2161580 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} + 90c34d9f99aafcc26de07beb0b3c85856de0fa46 7fae9524de068a420f7fa9f262669c461ada141f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} + 77174443ad6187ba2a216529d7c9785b5f309b70 cc55835562515ff390751032f9e735606c549e96 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} + 7fae9524de068a420f7fa9f262669c461ada141f e2ca321d00b4adb62525539578290e49e662da79 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'} + e2ca321d00b4adb62525539578290e49e662da79 744c2a22b7da8397bcbd2d472911d51404e54a38 ff95a51a90b9c6710e71bc8ea62c382a5d45e500 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'split', 'user': 'test'} $ hg --config extensions.evolve= obslog --all - o dde94df880e9 (21) c_G - | split(parent, content) from b24bab30ac12 using split by test (Thu Jan 01 00:00:00 1970 +0000) + o 744c2a22b7da (21) c_G + | split(parent, content) from e2ca321d00b4 using split by test (Thu Jan 01 00:00:00 1970 +0000) | - | @ e7ea874afbd5 (22) c_G - |/ split(parent, content) from b24bab30ac12 using split by test (Thu Jan 01 00:00:00 1970 +0000) + | @ ff95a51a90b9 (22) c_G + |/ split(parent, content) from e2ca321d00b4 using split by test (Thu Jan 01 00:00:00 1970 +0000) | - x b24bab30ac12 (20) c_G - | amended(content) from 907f7d3c2333 using amend by test (Thu Jan 01 00:00:00 1970 +0000) + x e2ca321d00b4 (20) c_G + | amended(content) from 7fae9524de06 using amend by test (Thu Jan 01 00:00:00 1970 +0000) | - x 907f7d3c2333 (18) c_G - | rebased(parent) from 3ab2eedae500 using rebase by test (Thu Jan 01 00:00:00 1970 +0000) + x 7fae9524de06 (18) c_G + | rebased(parent) from 90c34d9f99aa using rebase by test (Thu Jan 01 00:00:00 1970 +0000) | - x 3ab2eedae500 (13) c_G - | reauthored(user) from c7d60a180d05 using amend by test (Thu Jan 01 00:00:00 1970 +0000) + x 90c34d9f99aa (13) c_G + | reauthored(user) from 78da2467366f using amend by test (Thu Jan 01 00:00:00 1970 +0000) | - x c7d60a180d05 (6) c_G + x 78da2467366f (6) c_G $ hg export . # HG changeset patch # User test3 # Date 0 0 # Thu Jan 01 00:00:00 1970 +0000 - # Node ID e7ea874afbd5c17aeee366d39a828dbcb01682ce - # Parent dde94df880e97f4a1ee8c5408254b429b3d90204 + # Node ID ff95a51a90b9c6710e71bc8ea62c382a5d45e500 + # Parent 744c2a22b7da8397bcbd2d472911d51404e54a38 + # EXP-Topic-Namespace my-tns # EXP-Topic blue c_G - diff -r dde94df880e9 -r e7ea874afbd5 ggg + diff -r 744c2a22b7da -r ff95a51a90b9 ggg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ggg Thu Jan 01 00:00:00 1970 +0000 @@ -0,0 +1,1 @@ @@ -1018,12 +1022,13 @@ # User test3 # Date 0 0 # Thu Jan 01 00:00:00 1970 +0000 - # Node ID dde94df880e97f4a1ee8c5408254b429b3d90204 - # Parent f3328cd199dc389b850ca952f65a15a8e6dbc79b + # Node ID 744c2a22b7da8397bcbd2d472911d51404e54a38 + # Parent eed7b08171dd3b5a9359789531abc0bed2161580 + # EXP-Topic-Namespace my-tns # EXP-Topic blue c_G - diff -r f3328cd199dc -r dde94df880e9 Z + diff -r eed7b08171dd -r 744c2a22b7da Z --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Z Thu Jan 01 00:00:00 1970 +0000 @@ -0,0 +1,1 @@ diff -r a567e5e90b4f -r 144a5814f1ce tests/test-topic.t --- a/tests/test-topic.t Wed Aug 16 15:11:43 2023 -0300 +++ b/tests/test-topic.t Wed Oct 18 16:37:08 2023 -0300 @@ -848,6 +848,10 @@ abort: topic 'nonsense' does not exist [10] +Sanity checks for topicnamespace() revset + + $ tlog 'topicnamespace()' + Deactivate the topic. $ hg topics * fran (1 changesets) diff -r a567e5e90b4f -r 144a5814f1ce tests/testlib/retain-extras-ext.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/testlib/retain-extras-ext.py Wed Oct 18 16:37:08 2023 -0300 @@ -0,0 +1,16 @@ +""" +Wrap 'retained_extras_on_rebase' (from either mercurial or evolve) to retain +the "useful" extra. +""" + +from mercurial import rewriteutil + +try: + rewriteutil.retained_extras_on_rebase +except AttributeError: + # install the compatibility layer on older version + from hgext3rd.evolve import compat + compat.retained_extras_on_rebase # silence linter + +def extsetup(ui): + rewriteutil.retained_extras_on_rebase.add(b'useful')