hgext/transplant.py
author Brendan Cully <brendan@kublai.com>
Fri, 01 Dec 2006 14:30:17 -0800
changeset 3757 faed44bab17b
parent 3752 f902f409cd81
child 3758 889f7e74a0d9
permissions -rw-r--r--
transplant: clobber old series when transplant fails
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     1
# Patch transplanting extension for Mercurial
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     2
#
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     3
# Copyright 2006 Brendan Cully <brendan@kublai.com>
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     4
#
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     7
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     8
from mercurial.demandload import *
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
     9
from mercurial.i18n import gettext as _
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    10
demandload(globals(), 'os tempfile')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    11
demandload(globals(), 'mercurial:bundlerepo,cmdutil,commands,hg,merge,patch')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    12
demandload(globals(), 'mercurial:revlog,util')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    13
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    14
'''patch transplanting tool
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    15
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    16
This extension allows you to transplant patches from another branch.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    17
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    18
Transplanted patches are recorded in .hg/transplant/transplants, as a map
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    19
from a changeset hash to its hash in the source repository.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    20
'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    21
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    22
class transplantentry:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    23
    def __init__(self, lnode, rnode):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    24
        self.lnode = lnode
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    25
        self.rnode = rnode
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    26
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    27
class transplants:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    28
    def __init__(self, path=None, transplantfile=None, opener=None):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    29
        self.path = path
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    30
        self.transplantfile = transplantfile
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    31
        self.opener = opener
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    32
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    33
        if not opener:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    34
            self.opener = util.opener(self.path)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    35
        self.transplants = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    36
        self.dirty = False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    37
        self.read()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    38
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    39
    def read(self):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    40
        abspath = os.path.join(self.path, self.transplantfile)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    41
        if self.transplantfile and os.path.exists(abspath):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    42
            for line in self.opener(self.transplantfile).read().splitlines():
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    43
                lnode, rnode = map(revlog.bin, line.split(':'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    44
                self.transplants.append(transplantentry(lnode, rnode))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    45
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    46
    def write(self):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    47
        if self.dirty and self.transplantfile:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    48
            if not os.path.isdir(self.path):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    49
                os.mkdir(self.path)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    50
            fp = self.opener(self.transplantfile, 'w')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    51
            for c in self.transplants:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    52
                l, r = map(revlog.hex, (c.lnode, c.rnode))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    53
                fp.write(l + ':' + r + '\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    54
            fp.close()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    55
        self.dirty = False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    56
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    57
    def get(self, rnode):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    58
        return [t for t in self.transplants if t.rnode == rnode]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    59
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    60
    def set(self, lnode, rnode):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    61
        self.transplants.append(transplantentry(lnode, rnode))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    62
        self.dirty = True
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    63
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    64
    def remove(self, transplant):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    65
        del self.transplants[self.transplants.index(transplant)]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    66
        self.dirty = True
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    67
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    68
class transplanter:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    69
    def __init__(self, ui, repo):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    70
        self.ui = ui
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    71
        self.path = repo.join('transplant')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    72
        self.opener = util.opener(self.path)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    73
        self.transplants = transplants(self.path, 'transplants', opener=self.opener)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    74
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    75
    def applied(self, repo, node, parent):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    76
        '''returns True if a node is already an ancestor of parent
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    77
        or has already been transplanted'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    78
        if hasnode(repo, node):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    79
            if node in repo.changelog.reachable(parent, stop=node):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    80
                return True
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    81
        for t in self.transplants.get(node):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    82
            # it might have been stripped
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    83
            if not hasnode(repo, t.lnode):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    84
                self.transplants.remove(t)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    85
                return False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    86
            if t.lnode in repo.changelog.reachable(parent, stop=t.lnode):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    87
                return True
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    88
        return False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    89
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    90
    def apply(self, repo, source, revmap, merges, opts={}):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    91
        '''apply the revisions in revmap one by one in revision order'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    92
        revs = revmap.keys()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    93
        revs.sort()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    94
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    95
        p1, p2 = repo.dirstate.parents()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    96
        pulls = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    97
        diffopts = patch.diffopts(self.ui, opts)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    98
        diffopts.git = True
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
    99
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   100
        lock = repo.lock()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   101
        wlock = repo.wlock()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   102
        try:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   103
            for rev in revs:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   104
                node = revmap[rev]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   105
                revstr = '%s:%s' % (rev, revlog.short(node))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   106
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   107
                if self.applied(repo, node, p1):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   108
                    self.ui.warn(_('skipping already applied revision %s\n') %
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   109
                                 revstr)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   110
                    continue
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   111
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   112
                parents = source.changelog.parents(node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   113
                if not opts.get('filter'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   114
                    # If the changeset parent is the same as the wdir's parent,
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   115
                    # just pull it.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   116
                    if parents[0] == p1:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   117
                        pulls.append(node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   118
                        p1 = node
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   119
                        continue
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   120
                    if pulls:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   121
                        if source != repo:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   122
                            repo.pull(source, heads=pulls, lock=lock)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   123
                        merge.update(repo, pulls[-1], wlock=wlock)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   124
                        p1, p2 = repo.dirstate.parents()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   125
                        pulls = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   126
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   127
                domerge = False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   128
                if node in merges:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   129
                    # pulling all the merge revs at once would mean we couldn't
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   130
                    # transplant after the latest even if transplants before them
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   131
                    # fail.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   132
                    domerge = True
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   133
                    if not hasnode(repo, node):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   134
                        repo.pull(source, heads=[node], lock=lock)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   135
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   136
                if parents[1] != revlog.nullid:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   137
                    self.ui.note(_('skipping merge changeset %s:%s\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   138
                                 % (rev, revlog.short(node)))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   139
                    patchfile = None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   140
                else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   141
                    fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   142
                    fp = os.fdopen(fd, 'w')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   143
                    patch.export(source, [node], fp=fp, opts=diffopts)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   144
                    fp.close()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   145
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   146
                del revmap[rev]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   147
                if patchfile or domerge:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   148
                    try:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   149
                        n = self.applyone(repo, node, source.changelog.read(node),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   150
                                          patchfile, merge=domerge,
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   151
                                          log=opts.get('log'),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   152
                                          filter=opts.get('filter'),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   153
                                          lock=lock, wlock=wlock)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   154
                        if domerge:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   155
                            self.ui.status(_('%s merged at %s\n') % (revstr,
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   156
                                      revlog.short(n)))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   157
                        else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   158
                            self.ui.status(_('%s transplanted to %s\n') % (revlog.short(node),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   159
                                                                       revlog.short(n)))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   160
                    finally:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   161
                        if patchfile:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   162
                            os.unlink(patchfile)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   163
            if pulls:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   164
                repo.pull(source, heads=pulls, lock=lock)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   165
                merge.update(repo, pulls[-1], wlock=wlock)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   166
        finally:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   167
            self.saveseries(revmap, merges)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   168
            self.transplants.write()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   169
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   170
    def filter(self, filter, changelog, patchfile):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   171
        '''arbitrarily rewrite changeset before applying it'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   172
3752
f902f409cd81 transplant: "filtering %s\n"
Brendan Cully <brendan@kublai.com>
parents: 3726
diff changeset
   173
        self.ui.status('filtering %s\n' % patchfile)
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   174
        util.system('%s %s' % (filter, util.shellquote(patchfile)),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   175
                    environ={'HGUSER': changelog[1]},
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   176
                    onerr=util.Abort, errprefix=_('filter failed'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   177
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   178
    def applyone(self, repo, node, cl, patchfile, merge=False, log=False,
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   179
                 filter=None, lock=None, wlock=None):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   180
        '''apply the patch in patchfile to the repository as a transplant'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   181
        (manifest, user, (time, timezone), files, message) = cl[:5]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   182
        date = "%d %d" % (time, timezone)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   183
        extra = {'transplant_source': node}
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   184
        if filter:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   185
            self.filter(filter, cl, patchfile)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   186
            patchfile, message, user, date = patch.extract(self.ui, file(patchfile))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   187
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   188
        if log:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   189
            message += '\n(transplanted from %s)' % revlog.hex(node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   190
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   191
        self.ui.status(_('applying %s\n') % revlog.short(node))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   192
        self.ui.note('%s %s\n%s\n' % (user, date, message))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   193
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   194
        if not patchfile and not merge:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   195
            raise util.Abort(_('can only omit patchfile if merging'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   196
        if patchfile:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   197
            try:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   198
                files = {}
3726
752884db5037 transplant: recover added/removed files after failed application
Brendan Cully <brendan@kublai.com>
parents: 3725
diff changeset
   199
                try:
752884db5037 transplant: recover added/removed files after failed application
Brendan Cully <brendan@kublai.com>
parents: 3725
diff changeset
   200
                    fuzz = patch.patch(patchfile, self.ui, cwd=repo.root,
752884db5037 transplant: recover added/removed files after failed application
Brendan Cully <brendan@kublai.com>
parents: 3725
diff changeset
   201
                                       files=files)
752884db5037 transplant: recover added/removed files after failed application
Brendan Cully <brendan@kublai.com>
parents: 3725
diff changeset
   202
                    if not files:
752884db5037 transplant: recover added/removed files after failed application
Brendan Cully <brendan@kublai.com>
parents: 3725
diff changeset
   203
                        self.ui.warn(_('%s: empty changeset') % revlog.hex(node))
752884db5037 transplant: recover added/removed files after failed application
Brendan Cully <brendan@kublai.com>
parents: 3725
diff changeset
   204
                        return
752884db5037 transplant: recover added/removed files after failed application
Brendan Cully <brendan@kublai.com>
parents: 3725
diff changeset
   205
                finally:
752884db5037 transplant: recover added/removed files after failed application
Brendan Cully <brendan@kublai.com>
parents: 3725
diff changeset
   206
                    files = patch.updatedir(self.ui, repo, files, wlock=wlock)
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   207
                if filter:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   208
                    os.unlink(patchfile)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   209
            except Exception, inst:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   210
                if filter:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   211
                    os.unlink(patchfile)
3757
faed44bab17b transplant: clobber old series when transplant fails
Brendan Cully <brendan@kublai.com>
parents: 3752
diff changeset
   212
                seriespath = os.path.join(self.path, 'series')
faed44bab17b transplant: clobber old series when transplant fails
Brendan Cully <brendan@kublai.com>
parents: 3752
diff changeset
   213
                if os.path.exists(seriespath):
faed44bab17b transplant: clobber old series when transplant fails
Brendan Cully <brendan@kublai.com>
parents: 3752
diff changeset
   214
                    os.unlink(seriespath)
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   215
                p1 = repo.dirstate.parents()[0]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   216
                p2 = node
3725
ccc7a9eb0e5e transplant: preserve filter changes in --continue log
Brendan Cully <brendan@kublai.com>
parents: 3724
diff changeset
   217
                self.log(user, date, message, p1, p2, merge=merge)
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   218
                self.ui.write(str(inst) + '\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   219
                raise util.Abort(_('Fix up the merge and run hg transplant --continue'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   220
        else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   221
            files = None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   222
        if merge:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   223
            p1, p2 = repo.dirstate.parents()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   224
            repo.dirstate.setparents(p1, node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   225
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   226
        n = repo.commit(files, message, user, date, lock=lock, wlock=wlock,
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   227
                        extra=extra)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   228
        if not merge:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   229
            self.transplants.set(n, node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   230
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   231
        return n
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   232
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   233
    def resume(self, repo, source, opts=None):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   234
        '''recover last transaction and apply remaining changesets'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   235
        if os.path.exists(os.path.join(self.path, 'journal')):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   236
            n, node = self.recover(repo)
3724
ea523d6f5f1a transplant: fix --continue; add --continue test
Brendan Cully <brendan@kublai.com>
parents: 3723
diff changeset
   237
            self.ui.status(_('%s transplanted as %s\n') % (revlog.short(node),
ea523d6f5f1a transplant: fix --continue; add --continue test
Brendan Cully <brendan@kublai.com>
parents: 3723
diff changeset
   238
                                                           revlog.short(n)))
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   239
        seriespath = os.path.join(self.path, 'series')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   240
        if not os.path.exists(seriespath):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   241
            return
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   242
        nodes, merges = self.readseries()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   243
        revmap = {}
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   244
        for n in nodes:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   245
            revmap[source.changelog.rev(n)] = n
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   246
        os.unlink(seriespath)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   247
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   248
        self.apply(repo, source, revmap, merges, opts)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   249
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   250
    def recover(self, repo):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   251
        '''commit working directory using journal metadata'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   252
        node, user, date, message, parents = self.readlog()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   253
        merge = len(parents) == 2
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   254
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   255
        if not user or not date or not message or not parents[0]:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   256
            raise util.Abort(_('transplant log file is corrupt'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   257
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   258
        wlock = repo.wlock()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   259
        p1, p2 = repo.dirstate.parents()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   260
        if p1 != parents[0]:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   261
            raise util.Abort(_('working dir not at transplant parent %s') %
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   262
                             revlog.hex(parents[0]))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   263
        if merge:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   264
            repo.dirstate.setparents(p1, parents[1])
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   265
        n = repo.commit(None, message, user, date, wlock=wlock)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   266
        if not n:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   267
            raise util.Abort(_('commit failed'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   268
        if not merge:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   269
            self.transplants.set(n, node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   270
        self.unlog()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   271
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   272
        return n, node
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   273
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   274
    def readseries(self):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   275
        nodes = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   276
        merges = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   277
        cur = nodes
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   278
        for line in self.opener('series').read().splitlines():
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   279
            if line.startswith('# Merges'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   280
                cur = merges
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   281
                continue
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   282
            cur.append(revlog.bin(line))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   283
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   284
        return (nodes, merges)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   285
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   286
    def saveseries(self, revmap, merges):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   287
        if not revmap:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   288
            return
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   289
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   290
        if not os.path.isdir(self.path):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   291
            os.mkdir(self.path)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   292
        series = self.opener('series', 'w')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   293
        revs = revmap.keys()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   294
        revs.sort()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   295
        for rev in revs:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   296
            series.write(revlog.hex(revmap[rev]) + '\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   297
        if merges:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   298
            series.write('# Merges\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   299
            for m in merges:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   300
                series.write(revlog.hex(m) + '\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   301
        series.close()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   302
3725
ccc7a9eb0e5e transplant: preserve filter changes in --continue log
Brendan Cully <brendan@kublai.com>
parents: 3724
diff changeset
   303
    def log(self, user, date, message, p1, p2, merge=False):
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   304
        '''journal changelog metadata for later recover'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   305
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   306
        if not os.path.isdir(self.path):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   307
            os.mkdir(self.path)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   308
        fp = self.opener('journal', 'w')
3725
ccc7a9eb0e5e transplant: preserve filter changes in --continue log
Brendan Cully <brendan@kublai.com>
parents: 3724
diff changeset
   309
        fp.write('# User %s\n' % user)
ccc7a9eb0e5e transplant: preserve filter changes in --continue log
Brendan Cully <brendan@kublai.com>
parents: 3724
diff changeset
   310
        fp.write('# Date %s\n' % date)
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   311
        fp.write('# Node ID %s\n' % revlog.hex(p2))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   312
        fp.write('# Parent ' + revlog.hex(p1) + '\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   313
        if merge:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   314
            fp.write('# Parent ' + revlog.hex(p2) + '\n')
3725
ccc7a9eb0e5e transplant: preserve filter changes in --continue log
Brendan Cully <brendan@kublai.com>
parents: 3724
diff changeset
   315
        fp.write(message.rstrip() + '\n')
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   316
        fp.close()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   317
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   318
    def readlog(self):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   319
        parents = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   320
        message = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   321
        for line in self.opener('journal').read().splitlines():
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   322
            if line.startswith('# User '):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   323
                user = line[7:]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   324
            elif line.startswith('# Date '):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   325
                date = line[7:]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   326
            elif line.startswith('# Node ID '):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   327
                node = revlog.bin(line[10:])
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   328
            elif line.startswith('# Parent '):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   329
                parents.append(revlog.bin(line[9:]))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   330
            else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   331
                message.append(line)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   332
        return (node, user, date, '\n'.join(message), parents)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   333
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   334
    def unlog(self):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   335
        '''remove changelog journal'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   336
        absdst = os.path.join(self.path, 'journal')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   337
        if os.path.exists(absdst):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   338
            os.unlink(absdst)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   339
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   340
    def transplantfilter(self, repo, source, root):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   341
        def matchfn(node):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   342
            if self.applied(repo, node, root):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   343
                return False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   344
            if source.changelog.parents(node)[1] != revlog.nullid:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   345
                return False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   346
            extra = source.changelog.read(node)[5]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   347
            cnode = extra.get('transplant_source')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   348
            if cnode and self.applied(repo, cnode, root):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   349
                return False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   350
            return True
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   351
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   352
        return matchfn
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   353
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   354
def hasnode(repo, node):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   355
    try:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   356
        return repo.changelog.rev(node) != None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   357
    except revlog.RevlogError:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   358
        return False
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   359
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   360
def browserevs(ui, repo, nodes, opts):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   361
    '''interactively transplant changesets'''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   362
    def browsehelp(ui):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   363
        ui.write('y: transplant this changeset\n'
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   364
                 'n: skip this changeset\n'
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   365
                 'm: merge at this changeset\n'
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   366
                 'p: show patch\n'
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   367
                 'c: commit selected changesets\n'
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   368
                 'q: cancel transplant\n'
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   369
                 '?: show this help\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   370
3723
c828fca6f38a transplant: show_changeset moved to cmdutil
Brendan Cully <brendan@kublai.com>
parents: 3714
diff changeset
   371
    displayer = cmdutil.show_changeset(ui, repo, opts)
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   372
    transplants = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   373
    merges = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   374
    for node in nodes:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   375
        displayer.show(changenode=node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   376
        action = None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   377
        while not action:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   378
            action = ui.prompt(_('apply changeset? [ynmpcq?]:'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   379
            if action == '?':
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   380
                browsehelp(ui)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   381
                action = None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   382
            elif action == 'p':
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   383
                parent = repo.changelog.parents(node)[0]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   384
                patch.diff(repo, parent, node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   385
                action = None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   386
            elif action not in ('y', 'n', 'm', 'c', 'q'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   387
                ui.write('no such option\n')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   388
                action = None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   389
        if action == 'y':
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   390
            transplants.append(node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   391
        elif action == 'm':
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   392
            merges.append(node)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   393
        elif action == 'c':
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   394
            break
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   395
        elif action == 'q':
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   396
            transplants = ()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   397
            merges = ()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   398
            break
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   399
    return (transplants, merges)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   400
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   401
def transplant(ui, repo, *revs, **opts):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   402
    '''transplant changesets from another branch
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   403
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   404
    Selected changesets will be applied on top of the current working
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   405
    directory with the log of the original changeset. If --log is
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   406
    specified, log messages will have a comment appended of the form:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   407
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   408
    (transplanted from CHANGESETHASH)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   409
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   410
    You can rewrite the changelog message with the --filter option.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   411
    Its argument will be invoked with the current changelog message
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   412
    as $1 and the patch as $2.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   413
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   414
    If --source is specified, selects changesets from the named
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   415
    repository. If --branch is specified, selects changesets from the
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   416
    branch holding the named revision, up to that revision. If --all
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   417
    is specified, all changesets on the branch will be transplanted,
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   418
    otherwise you will be prompted to select the changesets you want.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   419
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   420
    hg transplant --branch REVISION --all will rebase the selected branch
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   421
    (up to the named revision) onto your current working directory.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   422
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   423
    You can optionally mark selected transplanted changesets as
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   424
    merge changesets. You will not be prompted to transplant any
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   425
    ancestors of a merged transplant, and you can merge descendants
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   426
    of them normally instead of transplanting them.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   427
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   428
    If no merges or revisions are provided, hg transplant will start
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   429
    an interactive changeset browser.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   430
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   431
    If a changeset application fails, you can fix the merge by hand and
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   432
    then resume where you left off by calling hg transplant --continue.
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   433
    '''
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   434
    def getoneitem(opts, item, errmsg):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   435
        val = opts.get(item)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   436
        if val:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   437
            if len(val) > 1:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   438
                raise util.Abort(errmsg)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   439
            else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   440
                return val[0]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   441
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   442
    def getremotechanges(repo, url):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   443
        sourcerepo = ui.expandpath(url)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   444
        source = hg.repository(ui, sourcerepo)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   445
        incoming = repo.findincoming(source, force=True)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   446
        if not incoming:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   447
            return (source, None, None)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   448
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   449
        bundle = None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   450
        if not source.local():
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   451
            cg = source.changegroup(incoming, 'incoming')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   452
            bundle = commands.write_bundle(cg, compress=False)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   453
            source = bundlerepo.bundlerepository(ui, repo.root, bundle)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   454
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   455
        return (source, incoming, bundle)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   456
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   457
    def incwalk(repo, incoming, branches, match=util.always):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   458
        if not branches:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   459
            branches=None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   460
        for node in repo.changelog.nodesbetween(incoming, branches)[0]:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   461
            if match(node):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   462
                yield node
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   463
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   464
    def transplantwalk(repo, root, branches, match=util.always):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   465
        if not branches:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   466
            branches = repo.heads()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   467
        ancestors = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   468
        for branch in branches:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   469
            ancestors.append(repo.changelog.ancestor(root, branch))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   470
        for node in repo.changelog.nodesbetween(ancestors, branches)[0]:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   471
            if match(node):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   472
                yield node
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   473
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   474
    def checkopts(opts, revs):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   475
        if opts.get('continue'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   476
            if filter(lambda opt: opts.get(opt), ('branch', 'all', 'merge')):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   477
                raise util.Abort(_('--continue is incompatible with branch, all or merge'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   478
            return
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   479
        if not (opts.get('source') or revs or
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   480
                opts.get('merge') or opts.get('branch')):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   481
            raise util.Abort(_('no source URL, branch tag or revision list provided'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   482
        if opts.get('all'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   483
            if not opts.get('branch'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   484
                raise util.Abort(_('--all requires a branch revision'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   485
            if revs:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   486
                raise util.Abort(_('--all is incompatible with a revision list'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   487
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   488
    checkopts(opts, revs)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   489
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   490
    if not opts.get('log'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   491
        opts['log'] = ui.config('transplant', 'log')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   492
    if not opts.get('filter'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   493
        opts['filter'] = ui.config('transplant', 'filter')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   494
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   495
    tp = transplanter(ui, repo)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   496
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   497
    p1, p2 = repo.dirstate.parents()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   498
    if p1 == revlog.nullid:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   499
        raise util.Abort(_('no revision checked out'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   500
    if not opts.get('continue'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   501
        if p2 != revlog.nullid:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   502
            raise util.Abort(_('outstanding uncommitted merges'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   503
        m, a, r, d = repo.status()[:4]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   504
        if m or a or r or d:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   505
            raise util.Abort(_('outstanding local changes'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   506
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   507
    bundle = None
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   508
    source = opts.get('source')
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   509
    if source:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   510
        (source, incoming, bundle) = getremotechanges(repo, source)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   511
    else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   512
        source = repo
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   513
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   514
    try:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   515
        if opts.get('continue'):
3724
ea523d6f5f1a transplant: fix --continue; add --continue test
Brendan Cully <brendan@kublai.com>
parents: 3723
diff changeset
   516
            tp.resume(repo, source, opts)
3714
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   517
            return
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   518
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   519
        tf=tp.transplantfilter(repo, source, p1)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   520
        if opts.get('prune'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   521
            prune = [source.lookup(r)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   522
                     for r in cmdutil.revrange(source, opts.get('prune'))]
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   523
            matchfn = lambda x: tf(x) and x not in prune
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   524
        else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   525
            matchfn = tf
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   526
        branches = map(source.lookup, opts.get('branch', ()))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   527
        merges = map(source.lookup, opts.get('merge', ()))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   528
        revmap = {}
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   529
        if revs:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   530
            for r in cmdutil.revrange(source, revs):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   531
                revmap[int(r)] = source.lookup(r)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   532
        elif opts.get('all') or not merges:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   533
            if source != repo:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   534
                alltransplants = incwalk(source, incoming, branches, match=matchfn)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   535
            else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   536
                alltransplants = transplantwalk(source, p1, branches, match=matchfn)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   537
            if opts.get('all'):
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   538
                revs = alltransplants
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   539
            else:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   540
                revs, newmerges = browserevs(ui, source, alltransplants, opts)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   541
                merges.extend(newmerges)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   542
            for r in revs:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   543
                revmap[source.changelog.rev(r)] = r
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   544
        for r in merges:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   545
            revmap[source.changelog.rev(r)] = r
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   546
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   547
        revs = revmap.keys()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   548
        revs.sort()
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   549
        pulls = []
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   550
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   551
        tp.apply(repo, source, revmap, merges, opts)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   552
    finally:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   553
        if bundle:
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   554
            os.unlink(bundle)
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   555
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   556
cmdtable = {
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   557
    "transplant":
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   558
        (transplant,
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   559
         [('s', 'source', '', _('pull patches from REPOSITORY')),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   560
          ('b', 'branch', [], _('pull patches from branch BRANCH')),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   561
          ('a', 'all', None, _('pull all changesets up to BRANCH')),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   562
          ('p', 'prune', [], _('skip over REV')),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   563
          ('m', 'merge', [], _('merge at REV')),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   564
          ('', 'log', None, _('append transplant info to log message')),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   565
          ('c', 'continue', None, _('continue last transplant session after repair')),
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   566
          ('', 'filter', '', _('filter changesets through FILTER'))],
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   567
         _('hg transplant [-s REPOSITORY] [-b BRANCH] [-p REV] [-m REV] [-n] REV...'))
198173f3957c Add transplant extension
Brendan Cully <brendan@kublai.com>
parents:
diff changeset
   568
}