annotate hgext/rebase.py @ 7329:fd4bf5269733

Do not abort with inotify extension enabled, but not supported by the system. And remove the "native support is required" message which is generated at an inappropriate location and is printed more than once when using 'hg status'.
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 07 Nov 2008 13:02:04 +0100
parents 0e2e371c7406
children 3e5db4228f8f
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
7127
9df67ee30ef5 help: better documentation intro for a few extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6964
diff changeset
8 '''move sets of revisions to a different ancestor
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
9
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
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
16 from mercurial import util, repair, merge, cmdutil, dispatch, commands
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
17 from mercurial import extensions, ancestor
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
18 from mercurial.commands import templateopts
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
19 from mercurial.node import nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
20 from mercurial.i18n import _
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
21 import os, errno
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
22
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
23 def rebasemerge(repo, rev, first=False):
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
24 'return the correct ancestor'
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
25 oldancestor = ancestor.ancestor
7298
0e2e371c7406 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7289
diff changeset
26
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
27 def newancestor(a, b, pfunc):
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
28 ancestor.ancestor = oldancestor
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
29 anc = ancestor.ancestor(a, b, pfunc)
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
30 if b == rev:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
31 return repo[rev].parents()[0].rev()
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
32 return ancestor.ancestor(a, b, pfunc)
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
33
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
34 if not first:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
35 ancestor.ancestor = newancestor
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
36 else:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
37 repo.ui.debug(_("First revision, do not change ancestor\n"))
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
38 stats = merge.update(repo, rev, True, True, False)
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
39 return stats
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
40
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
41 def rebase(ui, repo, **opts):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
42 """move changeset (and descendants) to a different branch
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
43
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
44 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
45 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
46 a master development tree.
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
47
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
48 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
49 with --continue or aborted with --abort.
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
50 """
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7216
diff changeset
51 originalwd = target = None
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
52 external = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
53 state = skipped = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
54
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
55 lock = wlock = None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
56 try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
57 lock = repo.lock()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
58 wlock = repo.wlock()
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 # Validate input and define rebasing points
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
61 destf = opts.get('dest', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
62 srcf = opts.get('source', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
63 basef = opts.get('base', None)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
64 contf = opts.get('continue')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
65 abortf = opts.get('abort')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
66 collapsef = opts.get('collapse', False)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
67 if contf or abortf:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
68 if contf and abortf:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
69 raise dispatch.ParseError('rebase',
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
70 _('cannot use both abort and continue'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
71 if collapsef:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
72 raise dispatch.ParseError('rebase',
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
73 _('cannot use collapse with continue or abort'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
74
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
75 if (srcf or basef or destf):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
76 raise dispatch.ParseError('rebase',
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
77 _('abort and continue do not allow specifying revisions'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
78
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
79 originalwd, target, state, collapsef, external = restorestatus(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
80 if abortf:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
81 abort(repo, originalwd, target, state)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
82 return
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
83 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
84 if srcf and basef:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
85 raise dispatch.ParseError('rebase', _('cannot specify both a '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
86 'revision and a base'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
87 cmdutil.bail_if_changed(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
88 result = buildstate(repo, destf, srcf, basef, collapsef)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
89 if result:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
90 originalwd, target, state, external = result
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
91 else: # Empty state built, nothing to rebase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
92 repo.ui.status(_('nothing to rebase\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
93 return
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
94
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
95 # Rebase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
96 targetancestors = list(repo.changelog.ancestors(target))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
97 targetancestors.append(target)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
98
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
99 for rev in util.sort(state):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
100 if state[rev] == -1:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
101 storestatus(repo, originalwd, target, state, collapsef,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
102 external)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
103 rebasenode(repo, rev, target, state, skipped, targetancestors,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
104 collapsef)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
105 ui.note(_('rebase merging completed\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
106
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
107 if collapsef:
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
108 p1, p2 = defineparents(repo, min(state), target,
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
109 state, targetancestors)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
110 concludenode(repo, rev, p1, external, state, collapsef,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
111 last=True, skipped=skipped)
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 if 'qtip' in repo.tags():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
114 updatemq(repo, state, skipped, **opts)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
115
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
116 if not opts.get('keep'):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
117 # Remove no more useful revisions
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
118 if (util.set(repo.changelog.descendants(min(state)))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
119 - util.set(state.keys())):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
120 ui.warn(_("warning: new changesets detected on source branch, "
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
121 "not stripping\n"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
122 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
123 repair.strip(repo.ui, repo, repo[min(state)].node(), "strip")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
124
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
125 clearstatus(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
126 ui.status(_("rebase completed\n"))
7130
204c7850c158 rebase: disable rollback after rebasing
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7127
diff changeset
127 if os.path.exists(repo.sjoin('undo')):
204c7850c158 rebase: disable rollback after rebasing
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7127
diff changeset
128 util.unlink(repo.sjoin('undo'))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
129 if skipped:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
130 ui.note(_("%d revisions have been skipped\n") % len(skipped))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
131 finally:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
132 del lock, wlock
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
133
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
134 def concludenode(repo, rev, p1, p2, state, collapse, last=False, skipped={}):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
135 """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
136 revision, commit otherwise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
137 """
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
138 repo.ui.debug(_(" set parents\n"))
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
139 if collapse and not last:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
140 repo.dirstate.setparents(repo[p1].node())
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
141 return None
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
142
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
143 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
144
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
145 # Commit, record the old nodeid
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
146 m, a, r = repo.status()[:3]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
147 newrev = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
148 try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
149 if last:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
150 commitmsg = 'Collapsed revision'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
151 for rebased in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
152 if rebased not in skipped:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
153 commitmsg += '\n* %s' % repo[rebased].description()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
154 commitmsg = repo.ui.edit(commitmsg, repo.ui.username())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
155 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
156 commitmsg = repo[rev].description()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
157 # Commit might fail if unresolved files exist
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
158 newrev = repo.commit(m+a+r,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
159 text=commitmsg,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
160 user=repo[rev].user(),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
161 date=repo[rev].date(),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
162 extra={'rebase_source': repo[rev].hex()})
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
163 return newrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
164 except util.Abort:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
165 # Invalidate the previous setparents
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
166 repo.dirstate.invalidate()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
167 raise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
168
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
169 def rebasenode(repo, rev, target, state, skipped, targetancestors, collapse):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
170 'Rebase a single revision'
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
171 repo.ui.debug(_("rebasing %d:%s\n") % (rev, repo[rev]))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
172
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
173 p1, p2 = defineparents(repo, rev, target, state, targetancestors)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
174
7298
0e2e371c7406 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7289
diff changeset
175 repo.ui.debug(_(" future parents are %d and %d\n") % (repo[p1].rev(),
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
176 repo[p2].rev()))
7298
0e2e371c7406 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7289
diff changeset
177
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
178 # Merge phase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
179 if len(repo.parents()) != 2:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
180 # Update to target and merge it with local
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
181 if repo['.'].rev() != repo[p1].rev():
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
182 repo.ui.debug(_(" update to %d:%s\n") % (repo[p1].rev(), repo[p1]))
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
183 merge.update(repo, p1, False, True, False)
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
184 else:
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
185 repo.ui.debug(_(" already in target\n"))
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
186 repo.dirstate.write()
7278
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
187 repo.ui.debug(_(" merge against %d:%s\n") % (repo[rev].rev(), repo[rev]))
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
188 first = repo[rev].rev() == repo[min(state)].rev()
45495d784ad6 rebase: avoid redundant merges (issue1301)
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents: 7216
diff changeset
189 stats = rebasemerge(repo, rev, first)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
190
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
191 if stats[3] > 0:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
192 raise util.Abort(_('fix unresolved conflicts with hg resolve then '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
193 'run hg rebase --continue'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
194 else: # we have an interrupted rebase
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
195 repo.ui.debug(_('resuming interrupted rebase\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
196
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
197
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
198 newrev = concludenode(repo, rev, p1, p2, state, collapse)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
199
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
200 # Update the state
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
201 if newrev is not None:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
202 state[rev] = repo[newrev].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
203 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
204 if not collapse:
6964
b3239badc711 i18n: mark strings for translation in rebase extension
Martin Geisler <mg@daimi.au.dk>
parents: 6923
diff changeset
205 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
206 repo.ui.debug(_('next revision set to %s\n') % p1)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
207 skipped[rev] = True
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
208 state[rev] = p1
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
209
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
210 def defineparents(repo, rev, target, state, targetancestors):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
211 '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
212 parents = repo[rev].parents()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
213 p1 = p2 = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
214
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
215 P1n = parents[0].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
216 if P1n in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
217 p1 = target
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
218 elif P1n in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
219 p1 = state[P1n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
220 else: # P1n external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
221 p1 = target
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
222 p2 = P1n
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
223
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
224 if len(parents) == 2 and parents[1].rev() not in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
225 P2n = parents[1].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
226 # interesting second parent
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
227 if P2n in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
228 if p1 == target: # P1n in targetancestors or external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
229 p1 = state[P2n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
230 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
231 p2 = state[P2n]
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
232 else: # P2n external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
233 if p2 != nullrev: # P1n external too => rev is a merged revision
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
234 raise util.Abort(_('cannot use revision %d as base, result '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
235 'would have 3 parents') % rev)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
236 p2 = P2n
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
237 return p1, p2
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
238
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
239 def updatemq(repo, state, skipped, **opts):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
240 'Update rebased mq patches - finalize and then import them'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
241 mqrebase = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
242 for p in repo.mq.applied:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
243 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
244 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
245 (repo[p.rev].rev(), p.name))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
246 mqrebase[repo[p.rev].rev()] = p.name
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
247
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
248 if mqrebase:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
249 repo.mq.finish(repo, mqrebase.keys())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
250
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
251 # We must start import from the newest revision
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
252 mq = mqrebase.keys()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
253 mq.sort()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
254 mq.reverse()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
255 for rev in mq:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
256 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
257 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
258 % (state[rev], mqrebase[rev]))
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
259 repo.mq.qimport(repo, (), patchname=mqrebase[rev],
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
260 git=opts.get('git', False),rev=[str(state[rev])])
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
261 repo.mq.save_dirty()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
262
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
263 def storestatus(repo, originalwd, target, state, collapse, external):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
264 'Store the current status to allow recovery'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
265 f = repo.opener("rebasestate", "w")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
266 f.write(repo[originalwd].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
267 f.write(repo[target].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
268 f.write(repo[external].hex() + '\n')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
269 f.write('%d\n' % int(collapse))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
270 for d, v in state.items():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
271 oldrev = repo[d].hex()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
272 newrev = repo[v].hex()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
273 f.write("%s:%s\n" % (oldrev, newrev))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
274 f.close()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
275 repo.ui.debug(_('rebase status stored\n'))
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 clearstatus(repo):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
278 'Remove the status files'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
279 if os.path.exists(repo.join("rebasestate")):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
280 util.unlink(repo.join("rebasestate"))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
281
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
282 def restorestatus(repo):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
283 'Restore a previously stored status'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
284 try:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
285 target = None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
286 collapse = False
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
287 external = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
288 state = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
289 f = repo.opener("rebasestate")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
290 for i, l in enumerate(f.read().splitlines()):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
291 if i == 0:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
292 originalwd = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
293 elif i == 1:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
294 target = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
295 elif i == 2:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
296 external = repo[l].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
297 elif i == 3:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
298 collapse = bool(int(l))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
299 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
300 oldrev, newrev = l.split(':')
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
301 state[repo[oldrev].rev()] = repo[newrev].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
302 repo.ui.debug(_('rebase status resumed\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
303 return originalwd, target, state, collapse, external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
304 except IOError, err:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
305 if err.errno != errno.ENOENT:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
306 raise
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
307 raise util.Abort(_('no rebase in progress'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
308
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
309 def abort(repo, originalwd, target, state):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
310 'Restore the repository to its original state'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
311 if util.set(repo.changelog.descendants(target)) - util.set(state.values()):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
312 repo.ui.warn(_("warning: new changesets detected on target branch, "
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
313 "not stripping\n"))
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 # Strip from the first rebased revision
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
316 merge.update(repo, repo[originalwd].rev(), False, True, False)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
317 rebased = filter(lambda x: x > -1, state.values())
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
318 if rebased:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
319 strippoint = min(rebased)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
320 repair.strip(repo.ui, repo, repo[strippoint].node(), "strip")
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
321 clearstatus(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
322 repo.ui.status(_('rebase aborted\n'))
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 def buildstate(repo, dest, src, base, collapse):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
325 'Define which revisions are going to be rebased and where'
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
326 state = {}
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
327 targetancestors = util.set()
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 if not dest:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
330 # Destination defaults to the latest revision in the current branch
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
331 branch = repo[None].branch()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
332 dest = repo[branch].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
333 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
334 if 'qtip' in repo.tags() and (repo[dest].hex() in
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
335 [s.rev for s in repo.mq.applied]):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
336 raise util.Abort(_('cannot rebase onto an applied mq patch'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
337 dest = repo[dest].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
338
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
339 if src:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
340 commonbase = repo[src].ancestor(repo[dest])
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
341 if commonbase == repo[src]:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
342 raise util.Abort(_('cannot rebase an ancestor'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
343 if commonbase == repo[dest]:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
344 raise util.Abort(_('cannot rebase a descendant'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
345 source = repo[src].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
346 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
347 if base:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
348 cwd = repo[base].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
349 else:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
350 cwd = repo['.'].rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
351
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
352 if cwd == dest:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
353 repo.ui.debug(_('already working on current\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
354 return None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
355
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
356 targetancestors = util.set(repo.changelog.ancestors(dest))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
357 if cwd in targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
358 repo.ui.debug(_('already working on the current branch\n'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
359 return None
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
360
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
361 cwdancestors = util.set(repo.changelog.ancestors(cwd))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
362 cwdancestors.add(cwd)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
363 rebasingbranch = cwdancestors - targetancestors
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
364 source = min(rebasingbranch)
6923
ebf1462f2145 strip trailing whitespace, replace tabs by spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6906
diff changeset
365
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
366 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
367 state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
368 external = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
369 if collapse:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
370 if not targetancestors:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
371 targetancestors = util.set(repo.changelog.ancestors(dest))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
372 for rev in state:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
373 # Check externals and fail if there are more than one
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
374 for p in repo[rev].parents():
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
375 if (p.rev() not in state and p.rev() != source
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
376 and p.rev() not in targetancestors):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
377 if external != nullrev:
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
378 raise util.Abort(_('unable to collapse, there is more '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
379 'than one external parent'))
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
380 external = p.rev()
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
381
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
382 state[source] = nullrev
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
383 return repo['.'].rev(), repo[dest].rev(), state, external
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
384
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
385 def pullrebase(orig, ui, repo, *args, **opts):
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
386 '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
387 if opts.get('rebase'):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
388 if opts.get('update'):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
389 raise util.Abort(_('--update and --rebase are not compatible'))
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 cmdutil.bail_if_changed(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
392 revsprepull = len(repo)
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
393 orig(ui, repo, *args, **opts)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
394 revspostpull = len(repo)
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
395 if revspostpull > revsprepull:
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
396 rebase(ui, repo, **opts)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
397 else:
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
398 orig(ui, repo, *args, **opts)
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
399
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
400 def uisetup(ui):
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
401 'Replace pull with a decorator to provide --rebase option'
7216
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
402 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
403 entry[1].append(('', 'rebase', None,
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
404 _("rebase working directory to branch head"))
292fb2ad2846 extensions: use new wrapper functions
Matt Mackall <mpm@selenic.com>
parents: 7213
diff changeset
405 )
6906
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
406
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
407 cmdtable = {
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
408 "rebase":
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
409 (rebase,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
410 [
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
411 ('', 'keep', False, _('keep original revisions')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
412 ('s', 'source', '', _('rebase from a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
413 ('b', 'base', '', _('rebase from the base of a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
414 ('d', 'dest', '', _('rebase onto a given revision')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
415 ('', 'collapse', False, _('collapse the rebased revisions')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
416 ('c', 'continue', False, _('continue an interrupted rebase')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
417 ('a', 'abort', False, _('abort an interrupted rebase')),] +
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
418 templateopts,
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
419 _('hg rebase [-s rev | -b rev] [-d rev] [--collapse] | [-c] | [-a] | '
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
420 '[--keep]')),
808f03f61ebe Add rebase extension
Stefano Tortarolo <stefano.tortarolo@gmail.com>
parents:
diff changeset
421 }