unshelve: unify logic around creating an unshelve changeset
This is a follow-up patch to
5162753c4c14 on addressing reviews
on the commit. This unifies the logic around creating an unshelve
changeset.
Differential Revision: https://phab.mercurial-scm.org/D6683
"""implements bookmark-based branching (EXPERIMENTAL)
- Disables creation of new branches (config: enable_branches=False).
- Requires an active bookmark on commit (config: require_bookmark=True).
- Doesn't move the active bookmark on update, only on commit.
- Requires '--rev' for moving an existing bookmark.
- Protects special bookmarks (config: protect=@).
flow related commands
:hg book NAME: create a new bookmark
:hg book NAME -r REV: move bookmark to revision (fast-forward)
:hg up|co NAME: switch to bookmark
:hg push -B .: push active bookmark
"""
from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
bookmarks,
commands,
error,
extensions,
registrar,
)
MY_NAME = 'bookflow'
configtable = {}
configitem = registrar.configitem(configtable)
configitem(MY_NAME, 'protect', ['@'])
configitem(MY_NAME, 'require-bookmark', True)
configitem(MY_NAME, 'enable-branches', False)
cmdtable = {}
command = registrar.command(cmdtable)
def commit_hook(ui, repo, **kwargs):
active = repo._bookmarks.active
if active:
if active in ui.configlist(MY_NAME, 'protect'):
raise error.Abort(
_('cannot commit, bookmark %s is protected') % active)
if not cwd_at_bookmark(repo, active):
raise error.Abort(
_('cannot commit, working directory out of sync with active bookmark'),
hint=_("run 'hg up %s'") % active)
elif ui.configbool(MY_NAME, 'require-bookmark', True):
raise error.Abort(_('cannot commit without an active bookmark'))
return 0
def bookmarks_update(orig, repo, parents, node):
if len(parents) == 2:
# called during commit
return orig(repo, parents, node)
else:
# called during update
return False
def bookmarks_addbookmarks(
orig, repo, tr, names, rev=None, force=False, inactive=False):
if not rev:
marks = repo._bookmarks
for name in names:
if name in marks:
raise error.Abort(_(
"bookmark %s already exists, to move use the --rev option"
) % name)
return orig(repo, tr, names, rev, force, inactive)
def commands_commit(orig, ui, repo, *args, **opts):
commit_hook(ui, repo)
return orig(ui, repo, *args, **opts)
def commands_pull(orig, ui, repo, *args, **opts):
rc = orig(ui, repo, *args, **opts)
active = repo._bookmarks.active
if active and not cwd_at_bookmark(repo, active):
ui.warn(_(
"working directory out of sync with active bookmark, run "
"'hg up %s'"
) % active)
return rc
def commands_branch(orig, ui, repo, label=None, **opts):
if label and not opts.get(r'clean') and not opts.get(r'rev'):
raise error.Abort(
_("creating named branches is disabled and you should use bookmarks"),
hint="see 'hg help bookflow'")
return orig(ui, repo, label, **opts)
def cwd_at_bookmark(repo, mark):
mark_id = repo._bookmarks[mark]
cur_id = repo.lookup('.')
return cur_id == mark_id
def uisetup(ui):
extensions.wrapfunction(bookmarks, 'update', bookmarks_update)
extensions.wrapfunction(bookmarks, 'addbookmarks', bookmarks_addbookmarks)
extensions.wrapcommand(commands.table, 'commit', commands_commit)
extensions.wrapcommand(commands.table, 'pull', commands_pull)
if not ui.configbool(MY_NAME, 'enable-branches'):
extensions.wrapcommand(commands.table, 'branch', commands_branch)