push: config option to control behavior when pushing to a publishing server
Pushing to a publishing server by mistake can lead to a difficult situation to
solve because evolution doesn't work on public changesets. This new
experimental config tries to help avoiding unintentionally (or at least being
aware of) pushing to publishing remotes.
`hg push --publish` can be used to make push succeed even when auto-publish is
set to 'abort'.
--- a/mercurial/configitems.py Fri Nov 30 17:42:55 2018 +0300
+++ b/mercurial/configitems.py Mon Nov 05 13:52:19 2018 +0800
@@ -449,6 +449,9 @@
coreconfigitem('experimental', 'archivemetatemplate',
default=dynamicdefault,
)
+coreconfigitem('experimental', 'auto-publish',
+ default='publish',
+)
coreconfigitem('experimental', 'bundle-phases',
default=False,
)
--- a/mercurial/exchange.py Fri Nov 30 17:42:55 2018 +0300
+++ b/mercurial/exchange.py Mon Nov 05 13:52:19 2018 +0800
@@ -334,6 +334,34 @@
heads = cl.heads()
return discovery.outgoing(repo, common, heads)
+def _checkpublish(pushop):
+ repo = pushop.repo
+ ui = repo.ui
+ behavior = ui.config('experimental', 'auto-publish')
+ if pushop.publish or behavior not in ('warn', 'confirm', 'abort'):
+ return
+ remotephases = listkeys(pushop.remote, 'phases')
+ if not remotephases.get('publishing', False):
+ return
+
+ if pushop.revs is None:
+ published = repo.filtered('served').revs('not public()')
+ else:
+ published = repo.revs('::%ln - public()', pushop.revs)
+ if published:
+ if behavior == 'warn':
+ ui.warn(_('%i changesets about to be published\n')
+ % len(published))
+ elif behavior == 'confirm':
+ if ui.promptchoice(_('push and publish %i changesets (yn)?'
+ '$$ &Yes $$ &No') % len(published)):
+ raise error.Abort(_('user quit'))
+ elif behavior == 'abort':
+ msg = _('push would publish %i changesets') % len(published)
+ hint = _("use --publish or adjust 'experimental.auto-publish'"
+ " config")
+ raise error.Abort(msg, hint=hint)
+
def _forcebundle1(op):
"""return true if a pull/push must use bundle1
@@ -533,6 +561,7 @@
lock or util.nullcontextmanager(), \
pushop.trmanager or util.nullcontextmanager():
pushop.repo.checkpush(pushop)
+ _checkpublish(pushop)
_pushdiscovery(pushop)
if not _forcebundle1(pushop):
_pushbundle2(pushop)
--- a/tests/test-phases-exchange.t Fri Nov 30 17:42:55 2018 +0300
+++ b/tests/test-phases-exchange.t Mon Nov 05 13:52:19 2018 +0800
@@ -1562,6 +1562,73 @@
$ killdaemons.py
+auto-publish config
+-------------------
+
+ $ hg init auto-publish-orig
+ $ hg clone -q auto-publish-orig auto-publish-clone
+ $ cd auto-publish-clone
+ $ mkcommit a-p-A
+ test-debug-phase: new rev 0: x -> 1
+ $ mkcommit a-p-B
+ test-debug-phase: new rev 1: x -> 1
+
+abort behavior
+
+ $ hg push --config experimental.auto-publish=abort
+ pushing to $TESTTMP/auto-publish-orig
+ abort: push would publish 2 changesets
+ (use --publish or adjust 'experimental.auto-publish' config)
+ [255]
+ $ hg push -r '.^' --config experimental.auto-publish=abort
+ pushing to $TESTTMP/auto-publish-orig
+ abort: push would publish 1 changesets
+ (use --publish or adjust 'experimental.auto-publish' config)
+ [255]
+
+--publish flag makes push succeed
+
+ $ hg push -r '.^' --publish --config experimental.auto-publish=abort
+ pushing to $TESTTMP/auto-publish-orig
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+ test-debug-phase: new rev 0: x -> 0
+ test-debug-phase: move rev 0: 1 -> 0
+
+warn behavior
+
+ $ hg push --config experimental.auto-publish=warn
+ pushing to $TESTTMP/auto-publish-orig
+ 1 changesets about to be published
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+ test-debug-phase: new rev 1: x -> 0
+ test-debug-phase: move rev 1: 1 -> 0
+
+confirm behavior
+
+ $ mkcommit a-p-C
+ test-debug-phase: new rev 2: x -> 1
+ $ hg push --config experimental.auto-publish=confirm
+ pushing to $TESTTMP/auto-publish-orig
+ push and publish 1 changesets (yn)? y
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+ test-debug-phase: new rev 2: x -> 0
+ test-debug-phase: move rev 2: 1 -> 0
+
+ $ cd ..
+
+
--publish flag
--------------