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.
--- 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
-------------------
--- 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'))
):
--- 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()
--- /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 <<EOF >>.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