# HG changeset patch # User Pulkit Goyal <7895pulkit@gmail.com> # Date 1512796408 -3600 # Node ID 8a772f0c54d9fee23eb89166db5d1debe402839d # Parent a18ca224e812361eacb252179cff33c236a5f10d topics: add a config to reject draft changeset without topic on a server This patch adds a new config option experimental.topic-mode.server which if sets to True, the server won't accept any draft changeset without topic on it. In case both `experimental.topic-mode.server` and `experimental.topic.publish-bare-branch` are set to True, the enforce-topic one is respected. Tests are added for it. The CHANGELOG file is also updated mentioning about the config option. diff -r a18ca224e812 -r 8a772f0c54d9 CHANGELOG --- a/CHANGELOG Sat Dec 09 05:05:39 2017 +0100 +++ b/CHANGELOG Sat Dec 09 06:13:28 2017 +0100 @@ -12,6 +12,8 @@ * add a new 'serverminitopic' extension for minimal server support (see `hg help -e serverminitopic` for details) + * add a new config option `experimental.topic-mode.server` using which a + server can reject draft changesets without topic 7.0.2 - in progress ------------------- diff -r a18ca224e812 -r 8a772f0c54d9 hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Sat Dec 09 05:05:39 2017 +0100 +++ b/hgext3rd/topic/__init__.py Sat Dec 09 06:13:28 2017 +0100 @@ -199,6 +199,9 @@ configitem('_internal', 'keep-topic', default=False, ) + configitem('experimental', 'topic-mode.server', + default=configitem.dynamicdefault, + ) def extsetup(ui): # register config that strictly belong to other code (thg, core, etc) @@ -223,6 +226,7 @@ return '' return self.extra().get(constants.extrakey, '') context.basectx.topic = _contexttopic + def _contexttopicidx(self): topic = self.topic() if not topic: @@ -421,7 +425,19 @@ origvalidator(tr2) tr.validator = validator - if (repo.ui.configbool('experimental', 'topic.publish-bare-branch') + topicmodeserver = repo.ui.config('experimental', + 'topic-mode.server', 'ignore') + ispush = (desc.startswith('push') or desc.startswith('serve')) + if (topicmodeserver != 'ignore' and ispush): + origvalidator = tr.validator + + def validator(tr2): + repo = reporef() + flow.rejectuntopicedchangeset(repo, tr2) + return origvalidator(tr2) + tr.validator = validator + + elif (repo.ui.configbool('experimental', 'topic.publish-bare-branch') and (desc.startswith('push') or desc.startswith('serve')) ): diff -r a18ca224e812 -r 8a772f0c54d9 hgext3rd/topic/flow.py --- a/hgext3rd/topic/flow.py Sat Dec 09 05:05:39 2017 +0100 +++ b/hgext3rd/topic/flow.py Sat Dec 09 06:13:28 2017 +0100 @@ -30,6 +30,31 @@ nodes = [cl.node(r) for r in topublish] repo._phasecache.advanceboundary(repo, tr, phases.public, nodes) +def rejectuntopicedchangeset(repo, tr): + """Reject the push if there are changeset without topic""" + if not tr.changes['revs']: # no new revs + return + + mode = repo.ui.config('experimental', 'topic-mode.server', 'ignore') + + revs = list(tr.changes['revs']) + untopiced = repo.revs('not public() and (%ld:) - hidden() - topic()', revs) + if untopiced: + num = len(untopiced) + fnode = repo[untopiced.first()].hex()[:10] + if num == 1: + msg = _("%s") % fnode + else: + msg = _("%s and %d more") % (fnode, num - 1) + if mode == 'warning': + fullmsg = _("pushed draft changeset without topic: %s\n") + repo.ui.warn(fullmsg % msg) + elif mode == 'enforce': + fullmsg = _("rejecting draft changesets: %s") + raise error.Abort(fullmsg % msg) + else: + repo.ui.warn(_("unknown 'topic-mode.server': %s\n" % mode)) + def wrappush(orig, repo, remote, *args, **kwargs): """interpret the --publish flag and pass it to the push operation""" newargs = kwargs.copy() diff -r a18ca224e812 -r 8a772f0c54d9 tests/test-topic-flow-reject-untopiced.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-topic-flow-reject-untopiced.t Sat Dec 09 06:13:28 2017 +0100 @@ -0,0 +1,171 @@ +Testing the config option for rejecting draft changeset without topic +The config option is "experimental.topic-mode.server" + + $ . "$TESTDIR/testlib/topic_setup.sh" + +Creating a server repo + + $ hg init server + $ cd server + $ cat <>.hg/hgrc + > [phases] + > publish=False + > [experimental] + > topic-mode.server = enforce + > EOF + + $ hg topic server + marked working directory as topic: server + $ for ch in a b c; do echo foo > $ch; hg ci -Aqm "Added "$ch; done + + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 2:a7b96f87a214 + | Added c server + o 1:d6a8197e192a + | Added b server + o 0:49a3f206c9ae + Added a server + + $ cd .. + +Creating a client repo + + $ hg clone server client + updating to branch default + switching to topic server + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd client + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 2:a7b96f87a214 + | Added c server + o 1:d6a8197e192a + | Added b server + o 0:49a3f206c9ae + Added a server + + $ hg topic + * server (3 changesets) + +Create a changeset without topic + + $ hg topic --clear + $ echo foo > d + $ hg ci -Aqm "added d" + + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 3:4e8b0e0237c6 + | added d + o 2:a7b96f87a214 + | Added c server + o 1:d6a8197e192a + | Added b server + o 0:49a3f206c9ae + Added a server + +Push a draft changeset without topic + + $ hg push ../server --new-branch + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + transaction abort! + rollback completed + abort: rejecting draft changesets: 4e8b0e0237 + [255] + + $ hg push ../server -f + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + transaction abort! + rollback completed + abort: rejecting draft changesets: 4e8b0e0237 + [255] + +Grow the stack with more changesets having topic + + $ hg topic client + marked working directory as topic: client + $ for ch in e f g; do echo foo > $ch; hg ci -Aqm "Added "$ch; done; + + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 6:42c4ac86452a + | Added g client + o 5:3dc456efb491 + | Added f client + o 4:18a516babc60 + | Added e client + o 3:4e8b0e0237c6 + | added d + o 2:a7b96f87a214 + | Added c server + o 1:d6a8197e192a + | Added b server + o 0:49a3f206c9ae + Added a server + +Pushing multiple changeset with some having topics and some not + + $ hg push ../server --new-branch + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 4 changes to 4 files + transaction abort! + rollback completed + abort: rejecting draft changesets: 4e8b0e0237 + [255] + +Testing case when both experimental.topic-mode.server and +experimental.topic.publish-bare-branch are set + + $ cd ../server + $ echo 'topic.publish-bare-branch=True' >> .hg/hgrc + $ cd ../client + $ hg push ../server --new-branch + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 4 changes to 4 files + transaction abort! + rollback completed + abort: rejecting draft changesets: 4e8b0e0237 + [255] + +Turning the changeset public and testing push + + $ hg phase -r 3 -p + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 6:42c4ac86452a + | Added g client + o 5:3dc456efb491 + | Added f client + o 4:18a516babc60 + | Added e client + o 3:4e8b0e0237c6 + | added d + o 2:a7b96f87a214 + | Added c + o 1:d6a8197e192a + | Added b + o 0:49a3f206c9ae + Added a + + $ hg push ../server + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 4 changes to 4 files + active topic 'server' is now empty