annotate hgext/rebase.py @ 10492:0e64d814d7d0 stable

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