hgext/bookflow.py
author Gregory Szorc <gregory.szorc@gmail.com>
Mon, 04 Feb 2019 09:00:52 -0800
changeset 41535 7a90ff8cd14c
parent 41031 b53c5651fcf6
child 43076 2372284d9457
permissions -rw-r--r--
crecord: use raw string for regular expression \s emits a SyntaxWarning in Python 3.8. Use a raw string to avoid escaping the \. Differential Revision: https://phab.mercurial-scm.org/D5819
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
40834
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     1
"""implements bookmark-based branching (EXPERIMENTAL)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     2
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     3
 - Disables creation of new branches (config: enable_branches=False).
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     4
 - Requires an active bookmark on commit (config: require_bookmark=True).
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     5
 - Doesn't move the active bookmark on update, only on commit.
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     6
 - Requires '--rev' for moving an existing bookmark.
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     7
 - Protects special bookmarks (config: protect=@).
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     8
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
     9
 flow related commands
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    10
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    11
    :hg book NAME: create a new bookmark
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    12
    :hg book NAME -r REV: move bookmark to revision (fast-forward)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    13
    :hg up|co NAME: switch to bookmark
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    14
    :hg push -B .: push active bookmark
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    15
"""
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    16
from __future__ import absolute_import
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    17
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    18
from mercurial.i18n import _
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    19
from mercurial import (
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    20
    bookmarks,
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    21
    commands,
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    22
    error,
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    23
    extensions,
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    24
    registrar,
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    25
)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    26
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    27
MY_NAME = 'bookflow'
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    28
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    29
configtable = {}
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    30
configitem = registrar.configitem(configtable)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    31
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    32
configitem(MY_NAME, 'protect', ['@'])
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    33
configitem(MY_NAME, 'require-bookmark', True)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    34
configitem(MY_NAME, 'enable-branches', False)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    35
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    36
cmdtable = {}
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    37
command = registrar.command(cmdtable)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    38
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    39
def commit_hook(ui, repo, **kwargs):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    40
    active = repo._bookmarks.active
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    41
    if active:
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    42
        if active in ui.configlist(MY_NAME, 'protect'):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    43
            raise error.Abort(
41031
b53c5651fcf6 py3: convert `'{}'.format(foo)` to `'%s' % foo` in the bookflow extension
Matt Harbison <matt_harbison@yahoo.com>
parents: 40834
diff changeset
    44
                _('cannot commit, bookmark %s is protected') % active)
40834
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    45
        if not cwd_at_bookmark(repo, active):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    46
            raise error.Abort(
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    47
       _('cannot commit, working directory out of sync with active bookmark'),
41031
b53c5651fcf6 py3: convert `'{}'.format(foo)` to `'%s' % foo` in the bookflow extension
Matt Harbison <matt_harbison@yahoo.com>
parents: 40834
diff changeset
    48
                hint=_("run 'hg up %s'") % active)
40834
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    49
    elif ui.configbool(MY_NAME, 'require-bookmark', True):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    50
        raise error.Abort(_('cannot commit without an active bookmark'))
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    51
    return 0
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    52
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    53
def bookmarks_update(orig, repo, parents, node):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    54
    if len(parents) == 2:
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    55
        # called during commit
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    56
        return orig(repo, parents, node)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    57
    else:
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    58
        # called during update
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    59
        return False
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    60
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    61
def bookmarks_addbookmarks(
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    62
        orig, repo, tr, names, rev=None, force=False, inactive=False):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    63
    if not rev:
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    64
        marks = repo._bookmarks
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    65
        for name in names:
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    66
            if name in marks:
41031
b53c5651fcf6 py3: convert `'{}'.format(foo)` to `'%s' % foo` in the bookflow extension
Matt Harbison <matt_harbison@yahoo.com>
parents: 40834
diff changeset
    67
                raise error.Abort(_(
b53c5651fcf6 py3: convert `'{}'.format(foo)` to `'%s' % foo` in the bookflow extension
Matt Harbison <matt_harbison@yahoo.com>
parents: 40834
diff changeset
    68
                    "bookmark %s already exists, to move use the --rev option"
b53c5651fcf6 py3: convert `'{}'.format(foo)` to `'%s' % foo` in the bookflow extension
Matt Harbison <matt_harbison@yahoo.com>
parents: 40834
diff changeset
    69
                    ) % name)
40834
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    70
    return orig(repo, tr, names, rev, force, inactive)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    71
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    72
def commands_commit(orig, ui, repo, *args, **opts):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    73
    commit_hook(ui, repo)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    74
    return orig(ui, repo, *args, **opts)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    75
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    76
def commands_pull(orig, ui, repo, *args, **opts):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    77
    rc = orig(ui, repo, *args, **opts)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    78
    active = repo._bookmarks.active
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    79
    if active and not cwd_at_bookmark(repo, active):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    80
        ui.warn(_(
41031
b53c5651fcf6 py3: convert `'{}'.format(foo)` to `'%s' % foo` in the bookflow extension
Matt Harbison <matt_harbison@yahoo.com>
parents: 40834
diff changeset
    81
            "working directory out of sync with active bookmark, run "
b53c5651fcf6 py3: convert `'{}'.format(foo)` to `'%s' % foo` in the bookflow extension
Matt Harbison <matt_harbison@yahoo.com>
parents: 40834
diff changeset
    82
            "'hg up %s'"
b53c5651fcf6 py3: convert `'{}'.format(foo)` to `'%s' % foo` in the bookflow extension
Matt Harbison <matt_harbison@yahoo.com>
parents: 40834
diff changeset
    83
        ) % active)
40834
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    84
    return rc
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    85
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    86
def commands_branch(orig, ui, repo, label=None, **opts):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    87
    if label and not opts.get(r'clean') and not opts.get(r'rev'):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    88
        raise error.Abort(
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    89
         _("creating named branches is disabled and you should use bookmarks"),
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    90
            hint="see 'hg help bookflow'")
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    91
    return orig(ui, repo, label, **opts)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    92
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    93
def cwd_at_bookmark(repo, mark):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    94
    mark_id = repo._bookmarks[mark]
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    95
    cur_id = repo.lookup('.')
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    96
    return cur_id == mark_id
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    97
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    98
def uisetup(ui):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
    99
    extensions.wrapfunction(bookmarks, 'update', bookmarks_update)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
   100
    extensions.wrapfunction(bookmarks, 'addbookmarks', bookmarks_addbookmarks)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
   101
    extensions.wrapcommand(commands.table, 'commit', commands_commit)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
   102
    extensions.wrapcommand(commands.table, 'pull', commands_pull)
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
   103
    if not ui.configbool(MY_NAME, 'enable-branches'):
9cec7a36bab8 bookflow: new extension for bookmark-based branching
idlsoft <idlsoft@gmail.com>
parents:
diff changeset
   104
        extensions.wrapcommand(commands.table, 'branch', commands_branch)