annotate hgext/rebase.py @ 7012:78341ea65d16

restructure helptable When looking up a help topic, the key is now only matched against the short names for each topic, and not the header. So hg help 'Environment Variables' must be replaced with hg help env
author Martin Geisler <mg@daimi.au.dk>
date Tue, 09 Sep 2008 21:32:39 +0200
parents b3239badc711
children 9df67ee30ef5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 #
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
7
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
8 ''' Rebasing feature
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
9
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
10 This extension lets you rebase changesets in an existing Mercurial repository.
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
11
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
12 For more information:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
13 http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
14 '''
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 from mercurial import util, repair, merge, cmdutil, dispatch, commands
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
17 from mercurial.commands import templateopts
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
18 from mercurial.node import nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
19 from mercurial.i18n import _
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
20 import os, errno
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
21
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
22 def rebase(ui, repo, **opts):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
23 """move changeset (and descendants) to a different branch
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
24
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
25 Rebase uses repeated merging to graft changesets from one part of history
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
26 onto another. This can be useful for linearizing local changes relative to
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
27 a master development tree.
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
28
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
29 If a rebase is interrupted to manually resolve a merge, it can be continued
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
30 with --continue or aborted with --abort.
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
31 """
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
32 originalwd = target = source = None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
33 external = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
34 state = skipped = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
35
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
36 lock = wlock = None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
37 try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
38 lock = repo.lock()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
39 wlock = repo.wlock()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
40
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
41 # Validate input and define rebasing points
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
42 destf = opts.get('dest', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
43 srcf = opts.get('source', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
44 basef = opts.get('base', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
45 contf = opts.get('continue')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
46 abortf = opts.get('abort')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
47 collapsef = opts.get('collapse', False)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
48 if contf or abortf:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
49 if contf and abortf:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
50 raise dispatch.ParseError('rebase',
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
51 _('cannot use both abort and continue'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
52 if collapsef:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
53 raise dispatch.ParseError('rebase',
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
54 _('cannot use collapse with continue or abort'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
55
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
56 if (srcf or basef or destf):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
57 raise dispatch.ParseError('rebase',
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
58 _('abort and continue do not allow specifying revisions'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
59
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
60 originalwd, target, state, collapsef, external = restorestatus(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
61 if abortf:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
62 abort(repo, originalwd, target, state)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
63 return
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
64 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
65 if srcf and basef:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
66 raise dispatch.ParseError('rebase', _('cannot specify both a '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
67 'revision and a base'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
68 cmdutil.bail_if_changed(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
69 result = buildstate(repo, destf, srcf, basef, collapsef)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
70 if result:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
71 originalwd, target, state, external = result
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
72 else: # Empty state built, nothing to rebase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
73 repo.ui.status(_('nothing to rebase\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
74 return
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
75
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
76 # Rebase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
77 targetancestors = list(repo.changelog.ancestors(target))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
78 targetancestors.append(target)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
79
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
80 for rev in util.sort(state):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
81 if state[rev] == -1:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
82 storestatus(repo, originalwd, target, state, collapsef,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
83 external)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
84 rebasenode(repo, rev, target, state, skipped, targetancestors,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
85 collapsef)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
86 ui.note(_('rebase merging completed\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
87
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
88 if collapsef:
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
89 p1, p2 = defineparents(repo, min(state), target,
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
90 state, targetancestors)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
91 concludenode(repo, rev, p1, external, state, collapsef,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
92 last=True, skipped=skipped)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
93
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
94 if 'qtip' in repo.tags():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
95 updatemq(repo, state, skipped, **opts)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
96
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
97 if not opts.get('keep'):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
98 # Remove no more useful revisions
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
99 if (util.set(repo.changelog.descendants(min(state)))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
100 - util.set(state.keys())):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
101 ui.warn(_("warning: new changesets detected on source branch, "
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
102 "not stripping\n"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
103 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
104 repair.strip(repo.ui, repo, repo[min(state)].node(), "strip")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
105
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
106 clearstatus(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
107 ui.status(_("rebase completed\n"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
108 if skipped:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
109 ui.note(_("%d revisions have been skipped\n") % len(skipped))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
110 finally:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
111 del lock, wlock
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
112
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
113 def concludenode(repo, rev, p1, p2, state, collapse, last=False, skipped={}):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
114 """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
115 revision, commit otherwise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
116 """
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
117 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
118
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
119 if collapse and not last:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
120 return None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
121
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
122 # Commit, record the old nodeid
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
123 m, a, r = repo.status()[:3]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
124 newrev = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
125 try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
126 if last:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
127 commitmsg = 'Collapsed revision'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
128 for rebased in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
129 if rebased not in skipped:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
130 commitmsg += '\n* %s' % repo[rebased].description()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
131 commitmsg = repo.ui.edit(commitmsg, repo.ui.username())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
132 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
133 commitmsg = repo[rev].description()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
134 # Commit might fail if unresolved files exist
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
135 newrev = repo.commit(m+a+r,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
136 text=commitmsg,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
137 user=repo[rev].user(),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
138 date=repo[rev].date(),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
139 extra={'rebase_source': repo[rev].hex()})
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
140 return newrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
141 except util.Abort:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
142 # Invalidate the previous setparents
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
143 repo.dirstate.invalidate()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
144 raise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
145
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
146 def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
147 'Rebase a single revision'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
148 repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev].node()))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
149
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
150 p1, p2 = defineparents(repo, rev, target, state, targetancestors)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
151
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
152 # Merge phase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
153 if len(repo.parents()) != 2:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
154 # Update to target and merge it with local
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
155 merge.update(repo, p1, False, True, False)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
156 repo.dirstate.write()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
157 stats = merge.update(repo, rev, True, False, False)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
158
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
159 if stats[3] > 0:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
160 raise util.Abort(_('fix unresolved conflicts with hg resolve then '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
161 'run hg rebase --continue'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
162 else: # we have an interrupted rebase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
163 repo.ui.debug(_('resuming interrupted rebase\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
164
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
165
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
166 newrev = concludenode(repo, rev, p1, p2, state, collapse)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
167
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
168 # Update the state
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
169 if newrev is not None:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
170 state[rev] = repo[newrev].rev()
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 if not collapse:
6964
b3239badc711 i18n: mark strings for translation in rebase extension
Martin Geisler <mg@daimi.au.dk>
parents: 6923
diff changeset
173 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
174 repo.ui.debug(_('next revision set to %s\n') % p1)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
175 skipped[rev] = True
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
176 state[rev] = p1
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
177
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
178 def defineparents(repo, rev, target, state, targetancestors):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
179 '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
180 parents = repo[rev].parents()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
181 p1 = p2 = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
182
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
183 P1n = parents[0].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
184 if P1n in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
185 p1 = target
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
186 elif P1n in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
187 p1 = state[P1n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
188 else: # P1n external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
189 p1 = target
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
190 p2 = P1n
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
191
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
192 if len(parents) == 2 and parents[1].rev() not in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
193 P2n = parents[1].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
194 # interesting second parent
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
195 if P2n in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
196 if p1 == target: # P1n in targetancestors or external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
197 p1 = state[P2n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
198 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
199 p2 = state[P2n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
200 else: # P2n external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
201 if p2 != nullrev: # P1n external too => rev is a merged revision
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
202 raise util.Abort(_('cannot use revision %d as base, result '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
203 'would have 3 parents') % rev)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
204 p2 = P2n
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
205 return p1, p2
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
206
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
207 def updatemq(repo, state, skipped, **opts):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
208 'Update rebased mq patches - finalize and then import them'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
209 mqrebase = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
210 for p in repo.mq.applied:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
211 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
212 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
213 (repo[p.rev].rev(), p.name))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
214 mqrebase[repo[p.rev].rev()] = p.name
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
215
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
216 if mqrebase:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
217 repo.mq.finish(repo, mqrebase.keys())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
218
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
219 # We must start import from the newest revision
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
220 mq = mqrebase.keys()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
221 mq.sort()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
222 mq.reverse()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
223 for rev in mq:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
224 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
225 repo.ui.debug(_('import mq patch %d (%s)\n')
b3239badc711 i18n: mark strings for translation in rebase extension
Martin Geisler <mg@daimi.au.dk>
parents: 6923
diff changeset
226 % (state[rev], mqrebase[rev]))
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
227 repo.mq.qimport(repo, (), patchname=mqrebase[rev],
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
228 git=opts.get('git', False),rev=[str(state[rev])])
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
229 repo.mq.save_dirty()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
230
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
231 def storestatus(repo, originalwd, target, state, collapse, external):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
232 'Store the current status to allow recovery'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
233 f = repo.opener("rebasestate", "w")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
234 f.write(repo[originalwd].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
235 f.write(repo[target].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
236 f.write(repo[external].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
237 f.write('%d\n' % int(collapse))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
238 for d, v in state.items():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
239 oldrev = repo[d].hex()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
240 newrev = repo[v].hex()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
241 f.write("%s:%s\n" % (oldrev, newrev))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
242 f.close()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
243 repo.ui.debug(_('rebase status stored\n'))
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 def clearstatus(repo):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
246 'Remove the status files'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
247 if os.path.exists(repo.join("rebasestate")):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
248 util.unlink(repo.join("rebasestate"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
249
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
250 def restorestatus(repo):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
251 'Restore a previously stored status'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
252 try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
253 target = None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
254 collapse = False
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
255 external = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
256 state = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
257 f = repo.opener("rebasestate")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
258 for i, l in enumerate(f.read().splitlines()):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
259 if i == 0:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
260 originalwd = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
261 elif i == 1:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
262 target = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
263 elif i == 2:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
264 external = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
265 elif i == 3:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
266 collapse = bool(int(l))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
267 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
268 oldrev, newrev = l.split(':')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
269 state[repo[oldrev].rev()] = repo[newrev].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
270 repo.ui.debug(_('rebase status resumed\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
271 return originalwd, target, state, collapse, external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
272 except IOError, err:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
273 if err.errno != errno.ENOENT:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
274 raise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
275 raise util.Abort(_('no rebase in progress'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
276
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
277 def abort(repo, originalwd, target, state):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
278 'Restore the repository to its original state'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
279 if util.set(repo.changelog.descendants(target)) - util.set(state.values()):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
280 repo.ui.warn(_("warning: new changesets detected on target branch, "
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
281 "not stripping\n"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
282 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
283 # Strip from the first rebased revision
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
284 merge.update(repo, repo[originalwd].rev(), False, True, False)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
285 rebased = filter(lambda x: x > -1, state.values())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
286 if rebased:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
287 strippoint = min(rebased)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
288 repair.strip(repo.ui, repo, repo[strippoint].node(), "strip")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
289 clearstatus(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
290 repo.ui.status(_('rebase aborted\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
291
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
292 def buildstate(repo, dest, src, base, collapse):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
293 'Define which revisions are going to be rebased and where'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
294 state = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
295 targetancestors = util.set()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
296
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
297 if not dest:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
298 # Destination defaults to the latest revision in the current branch
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
299 branch = repo[None].branch()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
300 dest = repo[branch].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
301 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
302 if 'qtip' in repo.tags() and (repo[dest].hex() in
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
303 [s.rev for s in repo.mq.applied]):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
304 raise util.Abort(_('cannot rebase onto an applied mq patch'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
305 dest = repo[dest].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
306
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
307 if src:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
308 commonbase = repo[src].ancestor(repo[dest])
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
309 if commonbase == repo[src]:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
310 raise util.Abort(_('cannot rebase an ancestor'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
311 if commonbase == repo[dest]:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
312 raise util.Abort(_('cannot rebase a descendant'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
313 source = repo[src].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
314 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
315 if base:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
316 cwd = repo[base].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
317 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
318 cwd = repo['.'].rev()
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 if cwd == dest:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
321 repo.ui.debug(_('already working on current\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
322 return None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
323
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
324 targetancestors = util.set(repo.changelog.ancestors(dest))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
325 if cwd in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
326 repo.ui.debug(_('already working on the current branch\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
327 return None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
328
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
329 cwdancestors = util.set(repo.changelog.ancestors(cwd))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
330 cwdancestors.add(cwd)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
331 rebasingbranch = cwdancestors - targetancestors
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
332 source = min(rebasingbranch)
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
333
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
334 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
335 state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
336 external = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
337 if collapse:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
338 if not targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
339 targetancestors = util.set(repo.changelog.ancestors(dest))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
340 for rev in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
341 # Check externals and fail if there are more than one
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
342 for p in repo[rev].parents():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
343 if (p.rev() not in state and p.rev() != source
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
344 and p.rev() not in targetancestors):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
345 if external != nullrev:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
346 raise util.Abort(_('unable to collapse, there is more '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
347 'than one external parent'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
348 external = p.rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
349
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
350 state[source] = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
351 return repo['.'].rev(), repo[dest].rev(), state, external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
352
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
353 def pulldelegate(pullfunction, repo, *args, **opts):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
354 '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
355 if opts.get('rebase'):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
356 if opts.get('update'):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
357 raise util.Abort(_('--update and --rebase are not compatible'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
358
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
359 cmdutil.bail_if_changed(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
360 revsprepull = len(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
361 pullfunction(repo.ui, repo, *args, **opts)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
362 revspostpull = len(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
363 if revspostpull > revsprepull:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
364 rebase(repo.ui, repo, **opts)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
365 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
366 pullfunction(repo.ui, repo, *args, **opts)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
367
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
368 def uisetup(ui):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
369 'Replace pull with a decorator to provide --rebase option'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
370 # cribbed from color.py
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
371 aliases, entry = cmdutil.findcmd(ui, 'pull', commands.table)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
372 for candidatekey, candidateentry in commands.table.iteritems():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
373 if candidateentry is entry:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
374 cmdkey, cmdentry = candidatekey, entry
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
375 break
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
376
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
377 decorator = lambda ui, repo, *args, **opts: \
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
378 pulldelegate(cmdentry[0], repo, *args, **opts)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
379 # make sure 'hg help cmd' still works
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
380 decorator.__doc__ = cmdentry[0].__doc__
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
381 decoratorentry = (decorator,) + cmdentry[1:]
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
382 rebaseopt = ('', 'rebase', None,
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
383 _("rebase working directory to branch head"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
384 decoratorentry[1].append(rebaseopt)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
385 commands.table[cmdkey] = decoratorentry
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
386
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
387 cmdtable = {
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
388 "rebase":
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
389 (rebase,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
390 [
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
391 ('', 'keep', False, _('keep original revisions')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
392 ('s', 'source', '', _('rebase from a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
393 ('b', 'base', '', _('rebase from the base of a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
394 ('d', 'dest', '', _('rebase onto a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
395 ('', 'collapse', False, _('collapse the rebased revisions')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
396 ('c', 'continue', False, _('continue an interrupted rebase')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
397 ('a', 'abort', False, _('abort an interrupted rebase')),] +
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
398 templateopts,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
399 _('hg rebase [-s rev | -b rev] [-d rev] [--collapse] | [-c] | [-a] | '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
400 '[--keep]')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
401 }