# HG changeset patch # User Anton Shestakov # Date 1687481497 10800 # Node ID 80d5d4e587f775fb454729d2a7a3202a2641c988 # Parent d324fa553620eac66849b0f1a118a2d2121540e0 topic: experimental config option and topic namespace checking in precheck() diff -r d324fa553620 -r 80d5d4e587f7 hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Mon Jul 17 16:20:16 2023 -0300 +++ b/hgext3rd/topic/__init__.py Thu Jun 22 21:51:37 2023 -0300 @@ -186,6 +186,7 @@ phases, pycompat, registrar, + rewriteutil, scmutil, smartset, templatefilters, @@ -273,6 +274,11 @@ 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'topic-mode.server', default=configitems.dynamicdefault, ) @@ -568,6 +574,15 @@ 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) def reposetup(ui, repo): @@ -1704,6 +1719,26 @@ 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 != b'none': with repo.wlock(): diff -r d324fa553620 -r 80d5d4e587f7 tests/test-namespaces-precheck.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-namespaces-precheck.t Thu Jun 22 21:51:37 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 ..