hgext/rebase.py
author Henrik Stuart <hg@hstuart.dk>
Sun, 07 Jun 2009 20:31:38 +0200
changeset 8846 b30775386d40
parent 8706 25e9c71b89de
child 8934 9dda4c73fc3b
permissions -rw-r--r--
acl: support for getting authenticated user from web server (issue298) Previously, the acl extension just read the current system user, which is fine for direct file system access and SSH, but will not work for HTTP(S) as that would return the web server process user identity rather than the authenticated user. An empty user is returned if the user is not authenticated.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
     1
# rebase.py - rebasing feature for mercurial
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
     2
#
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
     3
# Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8222
diff changeset
     5
# This software may be used and distributed according to the terms of the
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8222
diff changeset
     6
# GNU General Public License version 2, incorporated herein by reference.
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
     7
7127
9df67ee30ef5 help: better documentation intro for a few extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6964
diff changeset
     8
'''move sets of revisions to a different ancestor
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
     9
7999
b25110140573 rebase: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7955
diff changeset
    10
This extension lets you rebase changesets in an existing Mercurial
b25110140573 rebase: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7955
diff changeset
    11
repository.
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    12
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    13
For more information:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    14
http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    15
'''
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    16
7636
e3f8c6d6b72e error: move ParseError
Matt Mackall <mpm@selenic.com>
parents: 7622
diff changeset
    17
from mercurial import util, repair, merge, cmdutil, commands, error
7955
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
    18
from mercurial import extensions, ancestor, copies, patch
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    19
from mercurial.commands import templateopts
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    20
from mercurial.node import nullrev
8112
6ee71f78497c switch lock releasing in the extensions from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8076
diff changeset
    21
from mercurial.lock import release
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    22
from mercurial.i18n import _
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    23
import os, errno
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    24
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    25
def rebasemerge(repo, rev, first=False):
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    26
    'return the correct ancestor'
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    27
    oldancestor = ancestor.ancestor
7298
0e2e371c7406 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7289
diff changeset
    28
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    29
    def newancestor(a, b, pfunc):
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    30
        ancestor.ancestor = oldancestor
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    31
        if b == rev:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    32
            return repo[rev].parents()[0].rev()
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    33
        return ancestor.ancestor(a, b, pfunc)
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    34
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    35
    if not first:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    36
        ancestor.ancestor = newancestor
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    37
    else:
7599
7bf7c073375e lowercase ui.debug and assert output
Martin Geisler <mg@daimi.au.dk>
parents: 7468
diff changeset
    38
        repo.ui.debug(_("first revision, do not change ancestor\n"))
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    39
    stats = merge.update(repo, rev, True, True, False)
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    40
    return stats
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
    41
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    42
def rebase(ui, repo, **opts):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    43
    """move changeset (and descendants) to a different branch
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    44
7999
b25110140573 rebase: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7955
diff changeset
    45
    Rebase uses repeated merging to graft changesets from one part of
b25110140573 rebase: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7955
diff changeset
    46
    history onto another. This can be useful for linearizing local
b25110140573 rebase: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7955
diff changeset
    47
    changes relative to a master development tree.
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    48
7999
b25110140573 rebase: word-wrap help texts at 70 characters
Martin Geisler <mg@daimi.au.dk>
parents: 7955
diff changeset
    49
    If a rebase is interrupted to manually resolve a merge, it can be
8076
5ec526c1a32f help texts: write command line switches as -a/--abc
Martin Geisler <mg@lazybytes.net>
parents: 8031
diff changeset
    50
    continued with --continue/-c or aborted with --abort/-a.
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    51
    """
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7216
diff changeset
    52
    originalwd = target = None
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    53
    external = nullrev
8454
6d4bf1c1a003 rebase: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8270
diff changeset
    54
    state = {}
6d4bf1c1a003 rebase: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8270
diff changeset
    55
    skipped = set()
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    56
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    57
    lock = wlock = None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    58
    try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    59
        lock = repo.lock()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    60
        wlock = repo.wlock()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    61
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    62
        # Validate input and define rebasing points
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    63
        destf = opts.get('dest', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    64
        srcf = opts.get('source', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    65
        basef = opts.get('base', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    66
        contf = opts.get('continue')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    67
        abortf = opts.get('abort')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    68
        collapsef = opts.get('collapse', False)
7468
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
    69
        extrafn = opts.get('extrafn')
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
    70
        keepf = opts.get('keep', False)
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
    71
        keepbranchesf = opts.get('keepbranches', False)
7468
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
    72
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    73
        if contf or abortf:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    74
            if contf and abortf:
7636
e3f8c6d6b72e error: move ParseError
Matt Mackall <mpm@selenic.com>
parents: 7622
diff changeset
    75
                raise error.ParseError('rebase',
e3f8c6d6b72e error: move ParseError
Matt Mackall <mpm@selenic.com>
parents: 7622
diff changeset
    76
                                       _('cannot use both abort and continue'))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    77
            if collapsef:
7636
e3f8c6d6b72e error: move ParseError
Matt Mackall <mpm@selenic.com>
parents: 7622
diff changeset
    78
                raise error.ParseError(
e3f8c6d6b72e error: move ParseError
Matt Mackall <mpm@selenic.com>
parents: 7622
diff changeset
    79
                    'rebase', _('cannot use collapse with continue or abort'))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    80
8117
2b30d8488819 remove unnecessary outer parenthesis in if-statements
Martin Geisler <mg@lazybytes.net>
parents: 8112
diff changeset
    81
            if srcf or basef or destf:
7636
e3f8c6d6b72e error: move ParseError
Matt Mackall <mpm@selenic.com>
parents: 7622
diff changeset
    82
                raise error.ParseError('rebase',
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    83
                    _('abort and continue do not allow specifying revisions'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    84
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
    85
            (originalwd, target, state, collapsef, keepf,
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
    86
                                keepbranchesf, external) = restorestatus(repo)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    87
            if abortf:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    88
                abort(repo, originalwd, target, state)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    89
                return
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    90
        else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    91
            if srcf and basef:
7636
e3f8c6d6b72e error: move ParseError
Matt Mackall <mpm@selenic.com>
parents: 7622
diff changeset
    92
                raise error.ParseError('rebase', _('cannot specify both a '
e3f8c6d6b72e error: move ParseError
Matt Mackall <mpm@selenic.com>
parents: 7622
diff changeset
    93
                                                   'revision and a base'))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    94
            cmdutil.bail_if_changed(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    95
            result = buildstate(repo, destf, srcf, basef, collapsef)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    96
            if result:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    97
                originalwd, target, state, external = result
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
    98
            else: # Empty state built, nothing to rebase
8615
94ca38e63576 use ui instead of repo.ui when the former is in scope
Martin Geisler <mg@lazybytes.net>
parents: 8454
diff changeset
    99
                ui.status(_('nothing to rebase\n'))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   100
                return
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   101
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   102
        if keepbranchesf:
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   103
            if extrafn:
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   104
                raise error.ParseError(
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   105
                    'rebase', _('cannot use both keepbranches and extrafn'))
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   106
            def extrafn(ctx, extra):
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   107
                extra['branch'] = ctx.branch()
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   108
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   109
        # Rebase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   110
        targetancestors = list(repo.changelog.ancestors(target))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   111
        targetancestors.append(target)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   112
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 8163
diff changeset
   113
        for rev in sorted(state):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   114
            if state[rev] == -1:
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   115
                storestatus(repo, originalwd, target, state, collapsef, keepf,
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   116
                                                    keepbranchesf, external)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   117
                rebasenode(repo, rev, target, state, skipped, targetancestors,
7468
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   118
                                                       collapsef, extrafn)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   119
        ui.note(_('rebase merging completed\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   120
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   121
        if collapsef:
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
   122
            p1, p2 = defineparents(repo, min(state), target,
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   123
                                                        state, targetancestors)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   124
            concludenode(repo, rev, p1, external, state, collapsef,
7468
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   125
                         last=True, skipped=skipped, extrafn=extrafn)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   126
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   127
        if 'qtip' in repo.tags():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   128
            updatemq(repo, state, skipped, **opts)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   129
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   130
        if not keepf:
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   131
            # Remove no more useful revisions
8163
62d7287fe6b0 rebase, revlog: use set(x) instead of set(x.keys())
Martin Geisler <mg@lazybytes.net>
parents: 8150
diff changeset
   132
            if set(repo.changelog.descendants(min(state))) - set(state):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   133
                ui.warn(_("warning: new changesets detected on source branch, "
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   134
                                                        "not stripping\n"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   135
            else:
8615
94ca38e63576 use ui instead of repo.ui when the former is in scope
Martin Geisler <mg@lazybytes.net>
parents: 8454
diff changeset
   136
                repair.strip(ui, repo, repo[min(state)].node(), "strip")
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   137
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   138
        clearstatus(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   139
        ui.status(_("rebase completed\n"))
7130
204c7850c158 rebase: disable rollback after rebasing
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7127
diff changeset
   140
        if os.path.exists(repo.sjoin('undo')):
204c7850c158 rebase: disable rollback after rebasing
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7127
diff changeset
   141
            util.unlink(repo.sjoin('undo'))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   142
        if skipped:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   143
            ui.note(_("%d revisions have been skipped\n") % len(skipped))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   144
    finally:
8112
6ee71f78497c switch lock releasing in the extensions from gc to explicit
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8076
diff changeset
   145
        release(lock, wlock)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   146
8454
6d4bf1c1a003 rebase: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8270
diff changeset
   147
def concludenode(repo, rev, p1, p2, state, collapse, last=False, skipped=None,
7468
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   148
                 extrafn=None):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   149
    """Skip commit if collapsing has been required and rev is not the last
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   150
    revision, commit otherwise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   151
    """
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   152
    repo.ui.debug(_(" set parents\n"))
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   153
    if collapse and not last:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   154
        repo.dirstate.setparents(repo[p1].node())
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   155
        return None
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   156
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   157
    repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   158
8454
6d4bf1c1a003 rebase: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8270
diff changeset
   159
    if skipped is None:
6d4bf1c1a003 rebase: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8270
diff changeset
   160
        skipped = set()
6d4bf1c1a003 rebase: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8270
diff changeset
   161
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   162
    # Commit, record the old nodeid
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   163
    newrev = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   164
    try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   165
        if last:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   166
            commitmsg = 'Collapsed revision'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   167
            for rebased in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   168
                if rebased not in skipped:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   169
                    commitmsg += '\n* %s' % repo[rebased].description()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   170
            commitmsg = repo.ui.edit(commitmsg, repo.ui.username())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   171
        else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   172
            commitmsg = repo[rev].description()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   173
        # Commit might fail if unresolved files exist
7468
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   174
        extra = {'rebase_source': repo[rev].hex()}
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   175
        if extrafn:
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   176
            extrafn(repo[rev], extra)
8706
25e9c71b89de commit: drop the now-unused files parameter
Matt Mackall <mpm@selenic.com>
parents: 8702
diff changeset
   177
        newrev = repo.commit(text=commitmsg, user=repo[rev].user(),
25e9c71b89de commit: drop the now-unused files parameter
Matt Mackall <mpm@selenic.com>
parents: 8702
diff changeset
   178
                             date=repo[rev].date(), extra=extra)
8266
609ce91670d0 rebase: fix bug where --keepbranches could leave wrong branch in dirstate
Patrick Mezard <pmezard@gmail.com>
parents: 8242
diff changeset
   179
        repo.dirstate.setbranch(repo[newrev].branch())
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   180
        return newrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   181
    except util.Abort:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   182
        # Invalidate the previous setparents
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   183
        repo.dirstate.invalidate()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   184
        raise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   185
7468
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   186
def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse,
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   187
               extrafn):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   188
    'Rebase a single revision'
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   189
    repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev]))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   190
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   191
    p1, p2 = defineparents(repo, rev, target, state, targetancestors)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   192
7298
0e2e371c7406 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7289
diff changeset
   193
    repo.ui.debug(_(" future parents are %d and %d\n") % (repo[p1].rev(),
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   194
                                                            repo[p2].rev()))
7298
0e2e371c7406 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7289
diff changeset
   195
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   196
    # Merge phase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   197
    if len(repo.parents()) != 2:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   198
        # Update to target and merge it with local
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   199
        if repo['.'].rev() != repo[p1].rev():
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   200
            repo.ui.debug(_(" update to %d:%s\n") % (repo[p1].rev(), repo[p1]))
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   201
            merge.update(repo, p1, False, True, False)
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   202
        else:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   203
            repo.ui.debug(_(" already in target\n"))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   204
        repo.dirstate.write()
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   205
        repo.ui.debug(_(" merge against %d:%s\n") % (repo[rev].rev(), repo[rev]))
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   206
        first = repo[rev].rev() == repo[min(state)].rev()
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
   207
        stats = rebasemerge(repo, rev, first)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   208
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   209
        if stats[3] > 0:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   210
            raise util.Abort(_('fix unresolved conflicts with hg resolve then '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   211
                                                'run hg rebase --continue'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   212
    else: # we have an interrupted rebase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   213
        repo.ui.debug(_('resuming interrupted rebase\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   214
7954
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   215
    # Keep track of renamed files in the revision that is going to be rebased
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   216
    # Here we simulate the copies and renames in the source changeset
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   217
    cop, diver = copies.copies(repo, repo[rev], repo[target], repo[p2], True)
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   218
    m1 = repo[rev].manifest()
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   219
    m2 = repo[target].manifest()
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   220
    for k, v in cop.iteritems():
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   221
        if k in m1:
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   222
            if v in m1 or v in m2:
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   223
                repo.dirstate.copy(v, k)
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   224
                if v in m2 and v not in m1:
b969611064ae rebase: don't lose rename/copy data (Issue1423)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7952
diff changeset
   225
                    repo.dirstate.remove(v)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   226
7468
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   227
    newrev = concludenode(repo, rev, p1, p2, state, collapse,
3e5db4228f8f rebase: add support to keep branch names
Augie Fackler <durin42@gmail.com>
parents: 7298
diff changeset
   228
                          extrafn=extrafn)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   229
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   230
    # Update the state
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   231
    if newrev is not None:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   232
        state[rev] = repo[newrev].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   233
    else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   234
        if not collapse:
6964
b3239badc711 i18n: mark strings for translation in rebase extension
Martin Geisler <mg@daimi.au.dk>
parents: 6923
diff changeset
   235
            repo.ui.note(_('no changes, revision %d skipped\n') % rev)
b3239badc711 i18n: mark strings for translation in rebase extension
Martin Geisler <mg@daimi.au.dk>
parents: 6923
diff changeset
   236
            repo.ui.debug(_('next revision set to %s\n') % p1)
8454
6d4bf1c1a003 rebase: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8270
diff changeset
   237
            skipped.add(rev)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   238
        state[rev] = p1
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
   239
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   240
def defineparents(repo, rev, target, state, targetancestors):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   241
    'Return the new parent relationship of the revision that will be rebased'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   242
    parents = repo[rev].parents()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   243
    p1 = p2 = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   244
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   245
    P1n = parents[0].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   246
    if P1n in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   247
        p1 = target
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   248
    elif P1n in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   249
        p1 = state[P1n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   250
    else: # P1n external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   251
        p1 = target
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   252
        p2 = P1n
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   253
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   254
    if len(parents) == 2 and parents[1].rev() not in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   255
        P2n = parents[1].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   256
        # interesting second parent
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   257
        if P2n in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   258
            if p1 == target: # P1n in targetancestors or external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   259
                p1 = state[P2n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   260
            else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   261
                p2 = state[P2n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   262
        else: # P2n external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   263
            if p2 != nullrev: # P1n external too => rev is a merged revision
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   264
                raise util.Abort(_('cannot use revision %d as base, result '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   265
                        'would have 3 parents') % rev)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   266
            p2 = P2n
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   267
    return p1, p2
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   268
7955
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   269
def isagitpatch(repo, patchname):
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   270
    'Return true if the given patch is in git format'
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   271
    mqpatch = os.path.join(repo.mq.path, patchname)
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   272
    for line in patch.linereader(file(mqpatch, 'rb')):
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   273
        if line.startswith('diff --git'):
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   274
            return True
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   275
    return False
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   276
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   277
def updatemq(repo, state, skipped, **opts):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   278
    'Update rebased mq patches - finalize and then import them'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   279
    mqrebase = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   280
    for p in repo.mq.applied:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   281
        if repo[p.rev].rev() in state:
6964
b3239badc711 i18n: mark strings for translation in rebase extension
Martin Geisler <mg@daimi.au.dk>
parents: 6923
diff changeset
   282
            repo.ui.debug(_('revision %d is an mq patch (%s), finalize it.\n') %
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   283
                                        (repo[p.rev].rev(), p.name))
7955
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   284
            mqrebase[repo[p.rev].rev()] = (p.name, isagitpatch(repo, p.name))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   285
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   286
    if mqrebase:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   287
        repo.mq.finish(repo, mqrebase.keys())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   288
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   289
        # We must start import from the newest revision
8210
344751cd8cb8 replace various uses of list.reverse()
Matt Mackall <mpm@selenic.com>
parents: 8209
diff changeset
   290
        for rev in sorted(mqrebase, reverse=True):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   291
            if rev not in skipped:
6964
b3239badc711 i18n: mark strings for translation in rebase extension
Martin Geisler <mg@daimi.au.dk>
parents: 6923
diff changeset
   292
                repo.ui.debug(_('import mq patch %d (%s)\n')
7955
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   293
                              % (state[rev], mqrebase[rev][0]))
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   294
                repo.mq.qimport(repo, (), patchname=mqrebase[rev][0],
c3d4ff03ec72 rebase: keep original mq patch format (Issue1574)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7954
diff changeset
   295
                            git=mqrebase[rev][1],rev=[str(state[rev])])
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   296
        repo.mq.save_dirty()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   297
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   298
def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   299
                                                                external):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   300
    'Store the current status to allow recovery'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   301
    f = repo.opener("rebasestate", "w")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   302
    f.write(repo[originalwd].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   303
    f.write(repo[target].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   304
    f.write(repo[external].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   305
    f.write('%d\n' % int(collapse))
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   306
    f.write('%d\n' % int(keep))
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   307
    f.write('%d\n' % int(keepbranches))
7622
4dd7b28003d2 use dict.iteritems() rather than dict.items()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7599
diff changeset
   308
    for d, v in state.iteritems():
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   309
        oldrev = repo[d].hex()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   310
        newrev = repo[v].hex()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   311
        f.write("%s:%s\n" % (oldrev, newrev))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   312
    f.close()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   313
    repo.ui.debug(_('rebase status stored\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   314
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   315
def clearstatus(repo):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   316
    'Remove the status files'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   317
    if os.path.exists(repo.join("rebasestate")):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   318
        util.unlink(repo.join("rebasestate"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   319
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   320
def restorestatus(repo):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   321
    'Restore a previously stored status'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   322
    try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   323
        target = None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   324
        collapse = False
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   325
        external = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   326
        state = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   327
        f = repo.opener("rebasestate")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   328
        for i, l in enumerate(f.read().splitlines()):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   329
            if i == 0:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   330
                originalwd = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   331
            elif i == 1:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   332
                target = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   333
            elif i == 2:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   334
                external = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   335
            elif i == 3:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   336
                collapse = bool(int(l))
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   337
            elif i == 4:
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   338
                keep = bool(int(l))
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   339
            elif i == 5:
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   340
                keepbranches = bool(int(l))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   341
            else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   342
                oldrev, newrev = l.split(':')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   343
                state[repo[oldrev].rev()] = repo[newrev].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   344
        repo.ui.debug(_('rebase status resumed\n'))
7952
b214066b7e1d rebase: store/restore arguments correctly
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7951
diff changeset
   345
        return originalwd, target, state, collapse, keep, keepbranches, external
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   346
    except IOError, err:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   347
        if err.errno != errno.ENOENT:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   348
            raise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   349
        raise util.Abort(_('no rebase in progress'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   350
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   351
def abort(repo, originalwd, target, state):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   352
    'Restore the repository to its original state'
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8117
diff changeset
   353
    if set(repo.changelog.descendants(target)) - set(state.values()):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   354
        repo.ui.warn(_("warning: new changesets detected on target branch, "
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   355
                                                    "not stripping\n"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   356
    else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   357
        # Strip from the first rebased revision
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   358
        merge.update(repo, repo[originalwd].rev(), False, True, False)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   359
        rebased = filter(lambda x: x > -1, state.values())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   360
        if rebased:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   361
            strippoint = min(rebased)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   362
            repair.strip(repo.ui, repo, repo[strippoint].node(), "strip")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   363
        clearstatus(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   364
        repo.ui.status(_('rebase aborted\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   365
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   366
def buildstate(repo, dest, src, base, collapse):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   367
    'Define which revisions are going to be rebased and where'
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8117
diff changeset
   368
    targetancestors = set()
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   369
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   370
    if not dest:
7877
eba7f12b0c51 cleanup: whitespace cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7875
diff changeset
   371
        # Destination defaults to the latest revision in the current branch
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   372
        branch = repo[None].branch()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   373
        dest = repo[branch].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   374
    else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   375
        if 'qtip' in repo.tags() and (repo[dest].hex() in
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   376
                                [s.rev for s in repo.mq.applied]):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   377
            raise util.Abort(_('cannot rebase onto an applied mq patch'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   378
        dest = repo[dest].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   379
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   380
    if src:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   381
        commonbase = repo[src].ancestor(repo[dest])
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   382
        if commonbase == repo[src]:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   383
            raise util.Abort(_('cannot rebase an ancestor'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   384
        if commonbase == repo[dest]:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   385
            raise util.Abort(_('cannot rebase a descendant'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   386
        source = repo[src].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   387
    else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   388
        if base:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   389
            cwd = repo[base].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   390
        else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   391
            cwd = repo['.'].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   392
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   393
        if cwd == dest:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   394
            repo.ui.debug(_('already working on current\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   395
            return None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   396
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8117
diff changeset
   397
        targetancestors = set(repo.changelog.ancestors(dest))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   398
        if cwd in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   399
            repo.ui.debug(_('already working on the current branch\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   400
            return None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   401
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8117
diff changeset
   402
        cwdancestors = set(repo.changelog.ancestors(cwd))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   403
        cwdancestors.add(cwd)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   404
        rebasingbranch = cwdancestors - targetancestors
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   405
        source = min(rebasingbranch)
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
   406
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   407
    repo.ui.debug(_('rebase onto %d starting from %d\n') % (dest, source))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   408
    state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   409
    external = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   410
    if collapse:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   411
        if not targetancestors:
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8117
diff changeset
   412
            targetancestors = set(repo.changelog.ancestors(dest))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   413
        for rev in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   414
            # Check externals and fail if there are more than one
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   415
            for p in repo[rev].parents():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   416
                if (p.rev() not in state and p.rev() != source
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   417
                            and p.rev() not in targetancestors):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   418
                    if external != nullrev:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   419
                        raise util.Abort(_('unable to collapse, there is more '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   420
                                'than one external parent'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   421
                    external = p.rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   422
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   423
    state[source] = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   424
    return repo['.'].rev(), repo[dest].rev(), state, external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   425
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
   426
def pullrebase(orig, ui, repo, *args, **opts):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   427
    'Call rebase after pull if the latter has been invoked with --rebase'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   428
    if opts.get('rebase'):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   429
        if opts.get('update'):
8242
aee8455ee8ec Fix typeerror when specifying both --rebase and --pull
Martijn Pieters <mj@zopatista.com>
parents: 7786
diff changeset
   430
            del opts['update']
7786
92455c1d6f83 rebase: pull --rebase updates if there is nothing to rebase
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7636
diff changeset
   431
            ui.debug(_('--update and --rebase are not compatible, ignoring '
92455c1d6f83 rebase: pull --rebase updates if there is nothing to rebase
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7636
diff changeset
   432
                                        'the update flag\n'))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   433
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   434
        cmdutil.bail_if_changed(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   435
        revsprepull = len(repo)
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
   436
        orig(ui, repo, *args, **opts)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   437
        revspostpull = len(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   438
        if revspostpull > revsprepull:
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
   439
            rebase(ui, repo, **opts)
7786
92455c1d6f83 rebase: pull --rebase updates if there is nothing to rebase
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7636
diff changeset
   440
            branch = repo[None].branch()
92455c1d6f83 rebase: pull --rebase updates if there is nothing to rebase
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7636
diff changeset
   441
            dest = repo[branch].rev()
92455c1d6f83 rebase: pull --rebase updates if there is nothing to rebase
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7636
diff changeset
   442
            if dest != repo['.'].rev():
92455c1d6f83 rebase: pull --rebase updates if there is nothing to rebase
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7636
diff changeset
   443
                # there was nothing to rebase we force an update
92455c1d6f83 rebase: pull --rebase updates if there is nothing to rebase
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7636
diff changeset
   444
                merge.update(repo, dest, False, False, False)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   445
    else:
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
   446
        orig(ui, repo, *args, **opts)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   447
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   448
def uisetup(ui):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   449
    'Replace pull with a decorator to provide --rebase option'
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
   450
    entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
   451
    entry[1].append(('', 'rebase', None,
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
   452
                     _("rebase working directory to branch head"))
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
   453
)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   454
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   455
cmdtable = {
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   456
"rebase":
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   457
        (rebase,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   458
        [
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   459
        ('s', 'source', '', _('rebase from a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   460
        ('b', 'base', '', _('rebase from the base of a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   461
        ('d', 'dest', '', _('rebase onto a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   462
        ('', 'collapse', False, _('collapse the rebased revisions')),
7951
4d9e8efb7326 rebase: correct help text
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7891
diff changeset
   463
        ('', 'keep', False, _('keep original revisions')),
4d9e8efb7326 rebase: correct help text
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7891
diff changeset
   464
        ('', 'keepbranches', False, _('keep original branches')),
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   465
        ('c', 'continue', False, _('continue an interrupted rebase')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   466
        ('a', 'abort', False, _('abort an interrupted rebase')),] +
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   467
         templateopts,
8031
813a02a4eda2 upper-case command line meta variables
Martin Geisler <mg@lazybytes.net>
parents: 7999
diff changeset
   468
        _('hg rebase [-s REV | -b REV] [-d REV] [--collapse] [--keep] '
7951
4d9e8efb7326 rebase: correct help text
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7891
diff changeset
   469
                            '[--keepbranches] | [-c] | [-a]')),
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
   470
}