hgext/bookflow.py
author Martin von Zweigbergk <martinvonz@google.com>
Tue, 19 Feb 2019 15:42:45 -0800
changeset 41756 49ad315b39ee
parent 41031 b53c5651fcf6
child 43076 2372284d9457
permissions -rw-r--r--
copies: do copy tracing based on ctx.p[12]copies() if configured This adds an option to do copy tracing in a changeset-optimized way. If the metadata is stored in filelogs, this is obviously going to be suboptimal. The point is that it provides a way of transitioning to changeset-stored metadata. Some of the tests behave a little differently, but they all seem resonable to me. The config option may very well be renamed later when it's clearer what options we want and how they will behave. When the test suite is run with --extra-config-opt to use the new copy tracing, all tests pass, besides test-copies.t (which fails in the same way as you can see in this patch). `hg debugpathcopies 4.0 4.8` reports 82 copies. With this option enabled, the only difference is this: -mercurial/pure/bdiff.py -> mercurial/cffi/bdiff.py +setup_bdiff_cffi.py -> mercurial/cffi/bdiff.py I believe that happened because it was renamed in different ways on different sides of a merge and the new algorithm arbitrarily prefers copies that happened on p1. The runtime is about 0.85 seconds with the old copy tracing and 5.7 seconds with the new copy tracing. That's kind of slow, but actually better than I had expected. Differential Revision: https://phab.mercurial-scm.org/D5991
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)