##// END OF EJS Templates
rebase: do not add second parent to rebased changeset (drop detach option) (BC)...
Pierre-Yves David -
r17005:50f43451 default
parent child Browse files
Show More
@@ -1,677 +1,702 b''
1 # rebase.py - rebasing feature for mercurial
1 # rebase.py - rebasing feature for mercurial
2 #
2 #
3 # Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
3 # Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''command to move sets of revisions to a different ancestor
8 '''command to move sets of revisions to a different ancestor
9
9
10 This extension lets you rebase changesets in an existing Mercurial
10 This extension lets you rebase changesets in an existing Mercurial
11 repository.
11 repository.
12
12
13 For more information:
13 For more information:
14 http://mercurial.selenic.com/wiki/RebaseExtension
14 http://mercurial.selenic.com/wiki/RebaseExtension
15 '''
15 '''
16
16
17 from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks
17 from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks
18 from mercurial import extensions, patch, scmutil, phases
18 from mercurial import extensions, patch, scmutil, phases
19 from mercurial.commands import templateopts
19 from mercurial.commands import templateopts
20 from mercurial.node import nullrev
20 from mercurial.node import nullrev
21 from mercurial.lock import release
21 from mercurial.lock import release
22 from mercurial.i18n import _
22 from mercurial.i18n import _
23 import os, errno
23 import os, errno
24
24
25 nullmerge = -2
25 nullmerge = -2
26
26
27 cmdtable = {}
27 cmdtable = {}
28 command = cmdutil.command(cmdtable)
28 command = cmdutil.command(cmdtable)
29 testedwith = 'internal'
29 testedwith = 'internal'
30
30
31 @command('rebase',
31 @command('rebase',
32 [('s', 'source', '',
32 [('s', 'source', '',
33 _('rebase from the specified changeset'), _('REV')),
33 _('rebase from the specified changeset'), _('REV')),
34 ('b', 'base', '',
34 ('b', 'base', '',
35 _('rebase from the base of the specified changeset '
35 _('rebase from the base of the specified changeset '
36 '(up to greatest common ancestor of base and dest)'),
36 '(up to greatest common ancestor of base and dest)'),
37 _('REV')),
37 _('REV')),
38 ('r', 'rev', [],
38 ('r', 'rev', [],
39 _('rebase these revisions'),
39 _('rebase these revisions'),
40 _('REV')),
40 _('REV')),
41 ('d', 'dest', '',
41 ('d', 'dest', '',
42 _('rebase onto the specified changeset'), _('REV')),
42 _('rebase onto the specified changeset'), _('REV')),
43 ('', 'collapse', False, _('collapse the rebased changesets')),
43 ('', 'collapse', False, _('collapse the rebased changesets')),
44 ('m', 'message', '',
44 ('m', 'message', '',
45 _('use text as collapse commit message'), _('TEXT')),
45 _('use text as collapse commit message'), _('TEXT')),
46 ('e', 'edit', False, _('invoke editor on commit messages')),
46 ('e', 'edit', False, _('invoke editor on commit messages')),
47 ('l', 'logfile', '',
47 ('l', 'logfile', '',
48 _('read collapse commit message from file'), _('FILE')),
48 _('read collapse commit message from file'), _('FILE')),
49 ('', 'keep', False, _('keep original changesets')),
49 ('', 'keep', False, _('keep original changesets')),
50 ('', 'keepbranches', False, _('keep original branch names')),
50 ('', 'keepbranches', False, _('keep original branch names')),
51 ('D', 'detach', False, _('force detaching of source from its original '
51 ('D', 'detach', False, _('(DEPRECATED)')),
52 'branch')),
53 ('t', 'tool', '', _('specify merge tool')),
52 ('t', 'tool', '', _('specify merge tool')),
54 ('c', 'continue', False, _('continue an interrupted rebase')),
53 ('c', 'continue', False, _('continue an interrupted rebase')),
55 ('a', 'abort', False, _('abort an interrupted rebase'))] +
54 ('a', 'abort', False, _('abort an interrupted rebase'))] +
56 templateopts,
55 templateopts,
57 _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
56 _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
58 'hg rebase {-a|-c}'))
57 'hg rebase {-a|-c}'))
59 def rebase(ui, repo, **opts):
58 def rebase(ui, repo, **opts):
60 """move changeset (and descendants) to a different branch
59 """move changeset (and descendants) to a different branch
61
60
62 Rebase uses repeated merging to graft changesets from one part of
61 Rebase uses repeated merging to graft changesets from one part of
63 history (the source) onto another (the destination). This can be
62 history (the source) onto another (the destination). This can be
64 useful for linearizing *local* changes relative to a master
63 useful for linearizing *local* changes relative to a master
65 development tree.
64 development tree.
66
65
67 You should not rebase changesets that have already been shared
66 You should not rebase changesets that have already been shared
68 with others. Doing so will force everybody else to perform the
67 with others. Doing so will force everybody else to perform the
69 same rebase or they will end up with duplicated changesets after
68 same rebase or they will end up with duplicated changesets after
70 pulling in your rebased changesets.
69 pulling in your rebased changesets.
71
70
72 If you don't specify a destination changeset (``-d/--dest``),
71 If you don't specify a destination changeset (``-d/--dest``),
73 rebase uses the tipmost head of the current named branch as the
72 rebase uses the tipmost head of the current named branch as the
74 destination. (The destination changeset is not modified by
73 destination. (The destination changeset is not modified by
75 rebasing, but new changesets are added as its descendants.)
74 rebasing, but new changesets are added as its descendants.)
76
75
77 You can specify which changesets to rebase in two ways: as a
76 You can specify which changesets to rebase in two ways: as a
78 "source" changeset or as a "base" changeset. Both are shorthand
77 "source" changeset or as a "base" changeset. Both are shorthand
79 for a topologically related set of changesets (the "source
78 for a topologically related set of changesets (the "source
80 branch"). If you specify source (``-s/--source``), rebase will
79 branch"). If you specify source (``-s/--source``), rebase will
81 rebase that changeset and all of its descendants onto dest. If you
80 rebase that changeset and all of its descendants onto dest. If you
82 specify base (``-b/--base``), rebase will select ancestors of base
81 specify base (``-b/--base``), rebase will select ancestors of base
83 back to but not including the common ancestor with dest. Thus,
82 back to but not including the common ancestor with dest. Thus,
84 ``-b`` is less precise but more convenient than ``-s``: you can
83 ``-b`` is less precise but more convenient than ``-s``: you can
85 specify any changeset in the source branch, and rebase will select
84 specify any changeset in the source branch, and rebase will select
86 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
85 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
87 uses the parent of the working directory as the base.
86 uses the parent of the working directory as the base.
88
87
89 By default, rebase recreates the changesets in the source branch
88 By default, rebase recreates the changesets in the source branch
90 as descendants of dest and then destroys the originals. Use
89 as descendants of dest and then destroys the originals. Use
91 ``--keep`` to preserve the original source changesets. Some
90 ``--keep`` to preserve the original source changesets. Some
92 changesets in the source branch (e.g. merges from the destination
91 changesets in the source branch (e.g. merges from the destination
93 branch) may be dropped if they no longer contribute any change.
92 branch) may be dropped if they no longer contribute any change.
94
93
95 One result of the rules for selecting the destination changeset
94 One result of the rules for selecting the destination changeset
96 and source branch is that, unlike ``merge``, rebase will do
95 and source branch is that, unlike ``merge``, rebase will do
97 nothing if you are at the latest (tipmost) head of a named branch
96 nothing if you are at the latest (tipmost) head of a named branch
98 with two heads. You need to explicitly specify source and/or
97 with two heads. You need to explicitly specify source and/or
99 destination (or ``update`` to the other head, if it's the head of
98 destination (or ``update`` to the other head, if it's the head of
100 the intended source branch).
99 the intended source branch).
101
100
102 If a rebase is interrupted to manually resolve a merge, it can be
101 If a rebase is interrupted to manually resolve a merge, it can be
103 continued with --continue/-c or aborted with --abort/-a.
102 continued with --continue/-c or aborted with --abort/-a.
104
103
105 Returns 0 on success, 1 if nothing to rebase.
104 Returns 0 on success, 1 if nothing to rebase.
106 """
105 """
107 originalwd = target = None
106 originalwd = target = None
108 external = nullrev
107 external = nullrev
109 state = {}
108 state = {}
110 skipped = set()
109 skipped = set()
111 targetancestors = set()
110 targetancestors = set()
112
111
113 editor = None
112 editor = None
114 if opts.get('edit'):
113 if opts.get('edit'):
115 editor = cmdutil.commitforceeditor
114 editor = cmdutil.commitforceeditor
116
115
117 lock = wlock = None
116 lock = wlock = None
118 try:
117 try:
119 wlock = repo.wlock()
118 wlock = repo.wlock()
120 lock = repo.lock()
119 lock = repo.lock()
121
120
122 # Validate input and define rebasing points
121 # Validate input and define rebasing points
123 destf = opts.get('dest', None)
122 destf = opts.get('dest', None)
124 srcf = opts.get('source', None)
123 srcf = opts.get('source', None)
125 basef = opts.get('base', None)
124 basef = opts.get('base', None)
126 revf = opts.get('rev', [])
125 revf = opts.get('rev', [])
127 contf = opts.get('continue')
126 contf = opts.get('continue')
128 abortf = opts.get('abort')
127 abortf = opts.get('abort')
129 collapsef = opts.get('collapse', False)
128 collapsef = opts.get('collapse', False)
130 collapsemsg = cmdutil.logmessage(ui, opts)
129 collapsemsg = cmdutil.logmessage(ui, opts)
131 extrafn = opts.get('extrafn') # internal, used by e.g. hgsubversion
130 extrafn = opts.get('extrafn') # internal, used by e.g. hgsubversion
132 keepf = opts.get('keep', False)
131 keepf = opts.get('keep', False)
133 keepbranchesf = opts.get('keepbranches', False)
132 keepbranchesf = opts.get('keepbranches', False)
134 detachf = opts.get('detach', False)
135 # keepopen is not meant for use on the command line, but by
133 # keepopen is not meant for use on the command line, but by
136 # other extensions
134 # other extensions
137 keepopen = opts.get('keepopen', False)
135 keepopen = opts.get('keepopen', False)
138
136
139 if collapsemsg and not collapsef:
137 if collapsemsg and not collapsef:
140 raise util.Abort(
138 raise util.Abort(
141 _('message can only be specified with collapse'))
139 _('message can only be specified with collapse'))
142
140
143 if contf or abortf:
141 if contf or abortf:
144 if contf and abortf:
142 if contf and abortf:
145 raise util.Abort(_('cannot use both abort and continue'))
143 raise util.Abort(_('cannot use both abort and continue'))
146 if collapsef:
144 if collapsef:
147 raise util.Abort(
145 raise util.Abort(
148 _('cannot use collapse with continue or abort'))
146 _('cannot use collapse with continue or abort'))
149 if detachf:
150 raise util.Abort(_('cannot use detach with continue or abort'))
151 if srcf or basef or destf:
147 if srcf or basef or destf:
152 raise util.Abort(
148 raise util.Abort(
153 _('abort and continue do not allow specifying revisions'))
149 _('abort and continue do not allow specifying revisions'))
154 if opts.get('tool', False):
150 if opts.get('tool', False):
155 ui.warn(_('tool option will be ignored\n'))
151 ui.warn(_('tool option will be ignored\n'))
156
152
157 (originalwd, target, state, skipped, collapsef, keepf,
153 (originalwd, target, state, skipped, collapsef, keepf,
158 keepbranchesf, external) = restorestatus(repo)
154 keepbranchesf, external) = restorestatus(repo)
159 if abortf:
155 if abortf:
160 return abort(repo, originalwd, target, state)
156 return abort(repo, originalwd, target, state)
161 else:
157 else:
162 if srcf and basef:
158 if srcf and basef:
163 raise util.Abort(_('cannot specify both a '
159 raise util.Abort(_('cannot specify both a '
164 'source and a base'))
160 'source and a base'))
165 if revf and basef:
161 if revf and basef:
166 raise util.Abort(_('cannot specify both a '
162 raise util.Abort(_('cannot specify both a '
167 'revision and a base'))
163 'revision and a base'))
168 if revf and srcf:
164 if revf and srcf:
169 raise util.Abort(_('cannot specify both a '
165 raise util.Abort(_('cannot specify both a '
170 'revision and a source'))
166 'revision and a source'))
171 if detachf:
172 if not (srcf or revf):
173 raise util.Abort(
174 _('detach requires a revision to be specified'))
175 if basef:
176 raise util.Abort(_('cannot specify a base with detach'))
177
167
178 cmdutil.bailifchanged(repo)
168 cmdutil.bailifchanged(repo)
179
169
180 if not destf:
170 if not destf:
181 # Destination defaults to the latest revision in the
171 # Destination defaults to the latest revision in the
182 # current branch
172 # current branch
183 branch = repo[None].branch()
173 branch = repo[None].branch()
184 dest = repo[branch]
174 dest = repo[branch]
185 else:
175 else:
186 dest = scmutil.revsingle(repo, destf)
176 dest = scmutil.revsingle(repo, destf)
187
177
188 if revf:
178 if revf:
189 rebaseset = repo.revs('%lr', revf)
179 rebaseset = repo.revs('%lr', revf)
190 elif srcf:
180 elif srcf:
191 src = scmutil.revrange(repo, [srcf])
181 src = scmutil.revrange(repo, [srcf])
192 rebaseset = repo.revs('(%ld)::', src)
182 rebaseset = repo.revs('(%ld)::', src)
193 else:
183 else:
194 base = scmutil.revrange(repo, [basef or '.'])
184 base = scmutil.revrange(repo, [basef or '.'])
195 rebaseset = repo.revs(
185 rebaseset = repo.revs(
196 '(children(ancestor(%ld, %d)) and ::(%ld))::',
186 '(children(ancestor(%ld, %d)) and ::(%ld))::',
197 base, dest, base)
187 base, dest, base)
198
188
199 if rebaseset:
189 if rebaseset:
200 root = min(rebaseset)
190 root = min(rebaseset)
201 else:
191 else:
202 root = None
192 root = None
203
193
204 if not rebaseset:
194 if not rebaseset:
205 repo.ui.debug('base is ancestor of destination\n')
195 repo.ui.debug('base is ancestor of destination\n')
206 result = None
196 result = None
207 elif not keepf and list(repo.revs('first(children(%ld) - %ld)',
197 elif not keepf and list(repo.revs('first(children(%ld) - %ld)',
208 rebaseset, rebaseset)):
198 rebaseset, rebaseset)):
209 raise util.Abort(
199 raise util.Abort(
210 _("can't remove original changesets with"
200 _("can't remove original changesets with"
211 " unrebased descendants"),
201 " unrebased descendants"),
212 hint=_('use --keep to keep original changesets'))
202 hint=_('use --keep to keep original changesets'))
213 elif not keepf and not repo[root].mutable():
203 elif not keepf and not repo[root].mutable():
214 raise util.Abort(_("can't rebase immutable changeset %s")
204 raise util.Abort(_("can't rebase immutable changeset %s")
215 % repo[root],
205 % repo[root],
216 hint=_('see hg help phases for details'))
206 hint=_('see hg help phases for details'))
217 else:
207 else:
218 result = buildstate(repo, dest, rebaseset, detachf, collapsef)
208 result = buildstate(repo, dest, rebaseset, collapsef)
219
209
220 if not result:
210 if not result:
221 # Empty state built, nothing to rebase
211 # Empty state built, nothing to rebase
222 ui.status(_('nothing to rebase\n'))
212 ui.status(_('nothing to rebase\n'))
223 return 1
213 return 1
224 else:
214 else:
225 originalwd, target, state = result
215 originalwd, target, state = result
226 if collapsef:
216 if collapsef:
227 targetancestors = set(repo.changelog.ancestors([target]))
217 targetancestors = set(repo.changelog.ancestors([target]))
228 targetancestors.add(target)
218 targetancestors.add(target)
229 external = checkexternal(repo, state, targetancestors)
219 external = checkexternal(repo, state, targetancestors)
230
220
231 if keepbranchesf:
221 if keepbranchesf:
232 assert not extrafn, 'cannot use both keepbranches and extrafn'
222 assert not extrafn, 'cannot use both keepbranches and extrafn'
233 def extrafn(ctx, extra):
223 def extrafn(ctx, extra):
234 extra['branch'] = ctx.branch()
224 extra['branch'] = ctx.branch()
235 if collapsef:
225 if collapsef:
236 branches = set()
226 branches = set()
237 for rev in state:
227 for rev in state:
238 branches.add(repo[rev].branch())
228 branches.add(repo[rev].branch())
239 if len(branches) > 1:
229 if len(branches) > 1:
240 raise util.Abort(_('cannot collapse multiple named '
230 raise util.Abort(_('cannot collapse multiple named '
241 'branches'))
231 'branches'))
242
232
243
233
244 # Rebase
234 # Rebase
245 if not targetancestors:
235 if not targetancestors:
246 targetancestors = set(repo.changelog.ancestors([target]))
236 targetancestors = set(repo.changelog.ancestors([target]))
247 targetancestors.add(target)
237 targetancestors.add(target)
248
238
249 # Keep track of the current bookmarks in order to reset them later
239 # Keep track of the current bookmarks in order to reset them later
250 currentbookmarks = repo._bookmarks.copy()
240 currentbookmarks = repo._bookmarks.copy()
251
241
252 sortedstate = sorted(state)
242 sortedstate = sorted(state)
253 total = len(sortedstate)
243 total = len(sortedstate)
254 pos = 0
244 pos = 0
255 for rev in sortedstate:
245 for rev in sortedstate:
256 pos += 1
246 pos += 1
257 if state[rev] == -1:
247 if state[rev] == -1:
258 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, repo[rev])),
248 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, repo[rev])),
259 _('changesets'), total)
249 _('changesets'), total)
260 storestatus(repo, originalwd, target, state, collapsef, keepf,
250 storestatus(repo, originalwd, target, state, collapsef, keepf,
261 keepbranchesf, external)
251 keepbranchesf, external)
262 p1, p2 = defineparents(repo, rev, target, state,
252 p1, p2 = defineparents(repo, rev, target, state,
263 targetancestors)
253 targetancestors)
264 if len(repo.parents()) == 2:
254 if len(repo.parents()) == 2:
265 repo.ui.debug('resuming interrupted rebase\n')
255 repo.ui.debug('resuming interrupted rebase\n')
266 else:
256 else:
267 try:
257 try:
268 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
258 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
269 stats = rebasenode(repo, rev, p1, state, collapsef)
259 stats = rebasenode(repo, rev, p1, state, collapsef)
270 if stats and stats[3] > 0:
260 if stats and stats[3] > 0:
271 raise util.Abort(_('unresolved conflicts (see hg '
261 raise util.Abort(_('unresolved conflicts (see hg '
272 'resolve, then hg rebase --continue)'))
262 'resolve, then hg rebase --continue)'))
273 finally:
263 finally:
274 ui.setconfig('ui', 'forcemerge', '')
264 ui.setconfig('ui', 'forcemerge', '')
275 cmdutil.duplicatecopies(repo, rev, target)
265 cmdutil.duplicatecopies(repo, rev, target)
276 if not collapsef:
266 if not collapsef:
277 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn,
267 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn,
278 editor=editor)
268 editor=editor)
279 else:
269 else:
280 # Skip commit if we are collapsing
270 # Skip commit if we are collapsing
281 repo.setparents(repo[p1].node())
271 repo.setparents(repo[p1].node())
282 newrev = None
272 newrev = None
283 # Update the state
273 # Update the state
284 if newrev is not None:
274 if newrev is not None:
285 state[rev] = repo[newrev].rev()
275 state[rev] = repo[newrev].rev()
286 else:
276 else:
287 if not collapsef:
277 if not collapsef:
288 ui.note(_('no changes, revision %d skipped\n') % rev)
278 ui.note(_('no changes, revision %d skipped\n') % rev)
289 ui.debug('next revision set to %s\n' % p1)
279 ui.debug('next revision set to %s\n' % p1)
290 skipped.add(rev)
280 skipped.add(rev)
291 state[rev] = p1
281 state[rev] = p1
292
282
293 ui.progress(_('rebasing'), None)
283 ui.progress(_('rebasing'), None)
294 ui.note(_('rebase merging completed\n'))
284 ui.note(_('rebase merging completed\n'))
295
285
296 if collapsef and not keepopen:
286 if collapsef and not keepopen:
297 p1, p2 = defineparents(repo, min(state), target,
287 p1, p2 = defineparents(repo, min(state), target,
298 state, targetancestors)
288 state, targetancestors)
299 if collapsemsg:
289 if collapsemsg:
300 commitmsg = collapsemsg
290 commitmsg = collapsemsg
301 else:
291 else:
302 commitmsg = 'Collapsed revision'
292 commitmsg = 'Collapsed revision'
303 for rebased in state:
293 for rebased in state:
304 if rebased not in skipped and state[rebased] != nullmerge:
294 if rebased not in skipped and state[rebased] != nullmerge:
305 commitmsg += '\n* %s' % repo[rebased].description()
295 commitmsg += '\n* %s' % repo[rebased].description()
306 commitmsg = ui.edit(commitmsg, repo.ui.username())
296 commitmsg = ui.edit(commitmsg, repo.ui.username())
307 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
297 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
308 extrafn=extrafn, editor=editor)
298 extrafn=extrafn, editor=editor)
309
299
310 if 'qtip' in repo.tags():
300 if 'qtip' in repo.tags():
311 updatemq(repo, state, skipped, **opts)
301 updatemq(repo, state, skipped, **opts)
312
302
313 if currentbookmarks:
303 if currentbookmarks:
314 # Nodeids are needed to reset bookmarks
304 # Nodeids are needed to reset bookmarks
315 nstate = {}
305 nstate = {}
316 for k, v in state.iteritems():
306 for k, v in state.iteritems():
317 if v != nullmerge:
307 if v != nullmerge:
318 nstate[repo[k].node()] = repo[v].node()
308 nstate[repo[k].node()] = repo[v].node()
319
309
320 if not keepf:
310 if not keepf:
321 # Remove no more useful revisions
311 # Remove no more useful revisions
322 rebased = [rev for rev in state if state[rev] != nullmerge]
312 rebased = [rev for rev in state if state[rev] != nullmerge]
323 if rebased:
313 if rebased:
324 if set(repo.changelog.descendants([min(rebased)])) - set(state):
314 if set(repo.changelog.descendants([min(rebased)])) - set(state):
325 ui.warn(_("warning: new changesets detected "
315 ui.warn(_("warning: new changesets detected "
326 "on source branch, not stripping\n"))
316 "on source branch, not stripping\n"))
327 else:
317 else:
328 # backup the old csets by default
318 # backup the old csets by default
329 repair.strip(ui, repo, repo[min(rebased)].node(), "all")
319 repair.strip(ui, repo, repo[min(rebased)].node(), "all")
330
320
331 if currentbookmarks:
321 if currentbookmarks:
332 updatebookmarks(repo, nstate, currentbookmarks, **opts)
322 updatebookmarks(repo, nstate, currentbookmarks, **opts)
333
323
334 clearstatus(repo)
324 clearstatus(repo)
335 ui.note(_("rebase completed\n"))
325 ui.note(_("rebase completed\n"))
336 if os.path.exists(repo.sjoin('undo')):
326 if os.path.exists(repo.sjoin('undo')):
337 util.unlinkpath(repo.sjoin('undo'))
327 util.unlinkpath(repo.sjoin('undo'))
338 if skipped:
328 if skipped:
339 ui.note(_("%d revisions have been skipped\n") % len(skipped))
329 ui.note(_("%d revisions have been skipped\n") % len(skipped))
340 finally:
330 finally:
341 release(lock, wlock)
331 release(lock, wlock)
342
332
343 def checkexternal(repo, state, targetancestors):
333 def checkexternal(repo, state, targetancestors):
344 """Check whether one or more external revisions need to be taken in
334 """Check whether one or more external revisions need to be taken in
345 consideration. In the latter case, abort.
335 consideration. In the latter case, abort.
346 """
336 """
347 external = nullrev
337 external = nullrev
348 source = min(state)
338 source = min(state)
349 for rev in state:
339 for rev in state:
350 if rev == source:
340 if rev == source:
351 continue
341 continue
352 # Check externals and fail if there are more than one
342 # Check externals and fail if there are more than one
353 for p in repo[rev].parents():
343 for p in repo[rev].parents():
354 if (p.rev() not in state
344 if (p.rev() not in state
355 and p.rev() not in targetancestors):
345 and p.rev() not in targetancestors):
356 if external != nullrev:
346 if external != nullrev:
357 raise util.Abort(_('unable to collapse, there is more '
347 raise util.Abort(_('unable to collapse, there is more '
358 'than one external parent'))
348 'than one external parent'))
359 external = p.rev()
349 external = p.rev()
360 return external
350 return external
361
351
362 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
352 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None):
363 'Commit the changes and store useful information in extra'
353 'Commit the changes and store useful information in extra'
364 try:
354 try:
365 repo.setparents(repo[p1].node(), repo[p2].node())
355 repo.setparents(repo[p1].node(), repo[p2].node())
366 ctx = repo[rev]
356 ctx = repo[rev]
367 if commitmsg is None:
357 if commitmsg is None:
368 commitmsg = ctx.description()
358 commitmsg = ctx.description()
369 extra = {'rebase_source': ctx.hex()}
359 extra = {'rebase_source': ctx.hex()}
370 if extrafn:
360 if extrafn:
371 extrafn(ctx, extra)
361 extrafn(ctx, extra)
372 # Commit might fail if unresolved files exist
362 # Commit might fail if unresolved files exist
373 newrev = repo.commit(text=commitmsg, user=ctx.user(),
363 newrev = repo.commit(text=commitmsg, user=ctx.user(),
374 date=ctx.date(), extra=extra, editor=editor)
364 date=ctx.date(), extra=extra, editor=editor)
375 repo.dirstate.setbranch(repo[newrev].branch())
365 repo.dirstate.setbranch(repo[newrev].branch())
376 targetphase = max(ctx.phase(), phases.draft)
366 targetphase = max(ctx.phase(), phases.draft)
377 # retractboundary doesn't overwrite upper phase inherited from parent
367 # retractboundary doesn't overwrite upper phase inherited from parent
378 newnode = repo[newrev].node()
368 newnode = repo[newrev].node()
379 if newnode:
369 if newnode:
380 phases.retractboundary(repo, targetphase, [newnode])
370 phases.retractboundary(repo, targetphase, [newnode])
381 return newrev
371 return newrev
382 except util.Abort:
372 except util.Abort:
383 # Invalidate the previous setparents
373 # Invalidate the previous setparents
384 repo.dirstate.invalidate()
374 repo.dirstate.invalidate()
385 raise
375 raise
386
376
387 def rebasenode(repo, rev, p1, state, collapse):
377 def rebasenode(repo, rev, p1, state, collapse):
388 'Rebase a single revision'
378 'Rebase a single revision'
389 # Merge phase
379 # Merge phase
390 # Update to target and merge it with local
380 # Update to target and merge it with local
391 if repo['.'].rev() != repo[p1].rev():
381 if repo['.'].rev() != repo[p1].rev():
392 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
382 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
393 merge.update(repo, p1, False, True, False)
383 merge.update(repo, p1, False, True, False)
394 else:
384 else:
395 repo.ui.debug(" already in target\n")
385 repo.ui.debug(" already in target\n")
396 repo.dirstate.write()
386 repo.dirstate.write()
397 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
387 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
398 base = None
388 base = None
399 if repo[rev].rev() != repo[min(state)].rev():
389 if repo[rev].rev() != repo[min(state)].rev():
400 base = repo[rev].p1().node()
390 base = repo[rev].p1().node()
401 # When collapsing in-place, the parent is the common ancestor, we
391 # When collapsing in-place, the parent is the common ancestor, we
402 # have to allow merging with it.
392 # have to allow merging with it.
403 return merge.update(repo, rev, True, True, False, base, collapse)
393 return merge.update(repo, rev, True, True, False, base, collapse)
404
394
405 def defineparents(repo, rev, target, state, targetancestors):
395 def defineparents(repo, rev, target, state, targetancestors):
406 'Return the new parent relationship of the revision that will be rebased'
396 'Return the new parent relationship of the revision that will be rebased'
407 parents = repo[rev].parents()
397 parents = repo[rev].parents()
408 p1 = p2 = nullrev
398 p1 = p2 = nullrev
409
399
410 P1n = parents[0].rev()
400 P1n = parents[0].rev()
411 if P1n in targetancestors:
401 if P1n in targetancestors:
412 p1 = target
402 p1 = target
413 elif P1n in state:
403 elif P1n in state:
414 if state[P1n] == nullmerge:
404 if state[P1n] == nullmerge:
415 p1 = target
405 p1 = target
416 else:
406 else:
417 p1 = state[P1n]
407 p1 = state[P1n]
418 else: # P1n external
408 else: # P1n external
419 p1 = target
409 p1 = target
420 p2 = P1n
410 p2 = P1n
421
411
422 if len(parents) == 2 and parents[1].rev() not in targetancestors:
412 if len(parents) == 2 and parents[1].rev() not in targetancestors:
423 P2n = parents[1].rev()
413 P2n = parents[1].rev()
424 # interesting second parent
414 # interesting second parent
425 if P2n in state:
415 if P2n in state:
426 if p1 == target: # P1n in targetancestors or external
416 if p1 == target: # P1n in targetancestors or external
427 p1 = state[P2n]
417 p1 = state[P2n]
428 else:
418 else:
429 p2 = state[P2n]
419 p2 = state[P2n]
430 else: # P2n external
420 else: # P2n external
431 if p2 != nullrev: # P1n external too => rev is a merged revision
421 if p2 != nullrev: # P1n external too => rev is a merged revision
432 raise util.Abort(_('cannot use revision %d as base, result '
422 raise util.Abort(_('cannot use revision %d as base, result '
433 'would have 3 parents') % rev)
423 'would have 3 parents') % rev)
434 p2 = P2n
424 p2 = P2n
435 repo.ui.debug(" future parents are %d and %d\n" %
425 repo.ui.debug(" future parents are %d and %d\n" %
436 (repo[p1].rev(), repo[p2].rev()))
426 (repo[p1].rev(), repo[p2].rev()))
437 return p1, p2
427 return p1, p2
438
428
439 def isagitpatch(repo, patchname):
429 def isagitpatch(repo, patchname):
440 'Return true if the given patch is in git format'
430 'Return true if the given patch is in git format'
441 mqpatch = os.path.join(repo.mq.path, patchname)
431 mqpatch = os.path.join(repo.mq.path, patchname)
442 for line in patch.linereader(file(mqpatch, 'rb')):
432 for line in patch.linereader(file(mqpatch, 'rb')):
443 if line.startswith('diff --git'):
433 if line.startswith('diff --git'):
444 return True
434 return True
445 return False
435 return False
446
436
447 def updatemq(repo, state, skipped, **opts):
437 def updatemq(repo, state, skipped, **opts):
448 'Update rebased mq patches - finalize and then import them'
438 'Update rebased mq patches - finalize and then import them'
449 mqrebase = {}
439 mqrebase = {}
450 mq = repo.mq
440 mq = repo.mq
451 original_series = mq.fullseries[:]
441 original_series = mq.fullseries[:]
452 skippedpatches = set()
442 skippedpatches = set()
453
443
454 for p in mq.applied:
444 for p in mq.applied:
455 rev = repo[p.node].rev()
445 rev = repo[p.node].rev()
456 if rev in state:
446 if rev in state:
457 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
447 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
458 (rev, p.name))
448 (rev, p.name))
459 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
449 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
460 else:
450 else:
461 # Applied but not rebased, not sure this should happen
451 # Applied but not rebased, not sure this should happen
462 skippedpatches.add(p.name)
452 skippedpatches.add(p.name)
463
453
464 if mqrebase:
454 if mqrebase:
465 mq.finish(repo, mqrebase.keys())
455 mq.finish(repo, mqrebase.keys())
466
456
467 # We must start import from the newest revision
457 # We must start import from the newest revision
468 for rev in sorted(mqrebase, reverse=True):
458 for rev in sorted(mqrebase, reverse=True):
469 if rev not in skipped:
459 if rev not in skipped:
470 name, isgit = mqrebase[rev]
460 name, isgit = mqrebase[rev]
471 repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
461 repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
472 mq.qimport(repo, (), patchname=name, git=isgit,
462 mq.qimport(repo, (), patchname=name, git=isgit,
473 rev=[str(state[rev])])
463 rev=[str(state[rev])])
474 else:
464 else:
475 # Rebased and skipped
465 # Rebased and skipped
476 skippedpatches.add(mqrebase[rev][0])
466 skippedpatches.add(mqrebase[rev][0])
477
467
478 # Patches were either applied and rebased and imported in
468 # Patches were either applied and rebased and imported in
479 # order, applied and removed or unapplied. Discard the removed
469 # order, applied and removed or unapplied. Discard the removed
480 # ones while preserving the original series order and guards.
470 # ones while preserving the original series order and guards.
481 newseries = [s for s in original_series
471 newseries = [s for s in original_series
482 if mq.guard_re.split(s, 1)[0] not in skippedpatches]
472 if mq.guard_re.split(s, 1)[0] not in skippedpatches]
483 mq.fullseries[:] = newseries
473 mq.fullseries[:] = newseries
484 mq.seriesdirty = True
474 mq.seriesdirty = True
485 mq.savedirty()
475 mq.savedirty()
486
476
487 def updatebookmarks(repo, nstate, originalbookmarks, **opts):
477 def updatebookmarks(repo, nstate, originalbookmarks, **opts):
488 'Move bookmarks to their correct changesets'
478 'Move bookmarks to their correct changesets'
489 current = repo._bookmarkcurrent
479 current = repo._bookmarkcurrent
490 for k, v in originalbookmarks.iteritems():
480 for k, v in originalbookmarks.iteritems():
491 if v in nstate:
481 if v in nstate:
492 if nstate[v] != nullmerge:
482 if nstate[v] != nullmerge:
493 # reset the pointer if the bookmark was moved incorrectly
483 # reset the pointer if the bookmark was moved incorrectly
494 if k != current:
484 if k != current:
495 repo._bookmarks[k] = nstate[v]
485 repo._bookmarks[k] = nstate[v]
496
486
497 bookmarks.write(repo)
487 bookmarks.write(repo)
498
488
499 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
489 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
500 external):
490 external):
501 'Store the current status to allow recovery'
491 'Store the current status to allow recovery'
502 f = repo.opener("rebasestate", "w")
492 f = repo.opener("rebasestate", "w")
503 f.write(repo[originalwd].hex() + '\n')
493 f.write(repo[originalwd].hex() + '\n')
504 f.write(repo[target].hex() + '\n')
494 f.write(repo[target].hex() + '\n')
505 f.write(repo[external].hex() + '\n')
495 f.write(repo[external].hex() + '\n')
506 f.write('%d\n' % int(collapse))
496 f.write('%d\n' % int(collapse))
507 f.write('%d\n' % int(keep))
497 f.write('%d\n' % int(keep))
508 f.write('%d\n' % int(keepbranches))
498 f.write('%d\n' % int(keepbranches))
509 for d, v in state.iteritems():
499 for d, v in state.iteritems():
510 oldrev = repo[d].hex()
500 oldrev = repo[d].hex()
511 if v != nullmerge:
501 if v != nullmerge:
512 newrev = repo[v].hex()
502 newrev = repo[v].hex()
513 else:
503 else:
514 newrev = v
504 newrev = v
515 f.write("%s:%s\n" % (oldrev, newrev))
505 f.write("%s:%s\n" % (oldrev, newrev))
516 f.close()
506 f.close()
517 repo.ui.debug('rebase status stored\n')
507 repo.ui.debug('rebase status stored\n')
518
508
519 def clearstatus(repo):
509 def clearstatus(repo):
520 'Remove the status files'
510 'Remove the status files'
521 if os.path.exists(repo.join("rebasestate")):
511 if os.path.exists(repo.join("rebasestate")):
522 util.unlinkpath(repo.join("rebasestate"))
512 util.unlinkpath(repo.join("rebasestate"))
523
513
524 def restorestatus(repo):
514 def restorestatus(repo):
525 'Restore a previously stored status'
515 'Restore a previously stored status'
526 try:
516 try:
527 target = None
517 target = None
528 collapse = False
518 collapse = False
529 external = nullrev
519 external = nullrev
530 state = {}
520 state = {}
531 f = repo.opener("rebasestate")
521 f = repo.opener("rebasestate")
532 for i, l in enumerate(f.read().splitlines()):
522 for i, l in enumerate(f.read().splitlines()):
533 if i == 0:
523 if i == 0:
534 originalwd = repo[l].rev()
524 originalwd = repo[l].rev()
535 elif i == 1:
525 elif i == 1:
536 target = repo[l].rev()
526 target = repo[l].rev()
537 elif i == 2:
527 elif i == 2:
538 external = repo[l].rev()
528 external = repo[l].rev()
539 elif i == 3:
529 elif i == 3:
540 collapse = bool(int(l))
530 collapse = bool(int(l))
541 elif i == 4:
531 elif i == 4:
542 keep = bool(int(l))
532 keep = bool(int(l))
543 elif i == 5:
533 elif i == 5:
544 keepbranches = bool(int(l))
534 keepbranches = bool(int(l))
545 else:
535 else:
546 oldrev, newrev = l.split(':')
536 oldrev, newrev = l.split(':')
547 if newrev != str(nullmerge):
537 if newrev != str(nullmerge):
548 state[repo[oldrev].rev()] = repo[newrev].rev()
538 state[repo[oldrev].rev()] = repo[newrev].rev()
549 else:
539 else:
550 state[repo[oldrev].rev()] = int(newrev)
540 state[repo[oldrev].rev()] = int(newrev)
551 skipped = set()
541 skipped = set()
552 # recompute the set of skipped revs
542 # recompute the set of skipped revs
553 if not collapse:
543 if not collapse:
554 seen = set([target])
544 seen = set([target])
555 for old, new in sorted(state.items()):
545 for old, new in sorted(state.items()):
556 if new != nullrev and new in seen:
546 if new != nullrev and new in seen:
557 skipped.add(old)
547 skipped.add(old)
558 seen.add(new)
548 seen.add(new)
559 repo.ui.debug('computed skipped revs: %s\n' % skipped)
549 repo.ui.debug('computed skipped revs: %s\n' % skipped)
560 repo.ui.debug('rebase status resumed\n')
550 repo.ui.debug('rebase status resumed\n')
561 return (originalwd, target, state, skipped,
551 return (originalwd, target, state, skipped,
562 collapse, keep, keepbranches, external)
552 collapse, keep, keepbranches, external)
563 except IOError, err:
553 except IOError, err:
564 if err.errno != errno.ENOENT:
554 if err.errno != errno.ENOENT:
565 raise
555 raise
566 raise util.Abort(_('no rebase in progress'))
556 raise util.Abort(_('no rebase in progress'))
567
557
568 def abort(repo, originalwd, target, state):
558 def abort(repo, originalwd, target, state):
569 'Restore the repository to its original state'
559 'Restore the repository to its original state'
570 dstates = [s for s in state.values() if s != nullrev]
560 dstates = [s for s in state.values() if s != nullrev]
571 if [d for d in dstates if not repo[d].mutable()]:
561 if [d for d in dstates if not repo[d].mutable()]:
572 repo.ui.warn(_("warning: immutable rebased changeset detected, "
562 repo.ui.warn(_("warning: immutable rebased changeset detected, "
573 "can't abort\n"))
563 "can't abort\n"))
574 return -1
564 return -1
575
565
576 descendants = set()
566 descendants = set()
577 if dstates:
567 if dstates:
578 descendants = set(repo.changelog.descendants(dstates))
568 descendants = set(repo.changelog.descendants(dstates))
579 if descendants - set(dstates):
569 if descendants - set(dstates):
580 repo.ui.warn(_("warning: new changesets detected on target branch, "
570 repo.ui.warn(_("warning: new changesets detected on target branch, "
581 "can't abort\n"))
571 "can't abort\n"))
582 return -1
572 return -1
583 else:
573 else:
584 # Strip from the first rebased revision
574 # Strip from the first rebased revision
585 merge.update(repo, repo[originalwd].rev(), False, True, False)
575 merge.update(repo, repo[originalwd].rev(), False, True, False)
586 rebased = filter(lambda x: x > -1 and x != target, state.values())
576 rebased = filter(lambda x: x > -1 and x != target, state.values())
587 if rebased:
577 if rebased:
588 strippoint = min(rebased)
578 strippoint = min(rebased)
589 # no backup of rebased cset versions needed
579 # no backup of rebased cset versions needed
590 repair.strip(repo.ui, repo, repo[strippoint].node())
580 repair.strip(repo.ui, repo, repo[strippoint].node())
591 clearstatus(repo)
581 clearstatus(repo)
592 repo.ui.warn(_('rebase aborted\n'))
582 repo.ui.warn(_('rebase aborted\n'))
593 return 0
583 return 0
594
584
595 def buildstate(repo, dest, rebaseset, detach, collapse):
585 def buildstate(repo, dest, rebaseset, collapse):
596 '''Define which revisions are going to be rebased and where
586 '''Define which revisions are going to be rebased and where
597
587
598 repo: repo
588 repo: repo
599 dest: context
589 dest: context
600 rebaseset: set of rev
590 rebaseset: set of rev
601 detach: boolean'''
591 '''
602
592
603 # This check isn't strictly necessary, since mq detects commits over an
593 # This check isn't strictly necessary, since mq detects commits over an
604 # applied patch. But it prevents messing up the working directory when
594 # applied patch. But it prevents messing up the working directory when
605 # a partially completed rebase is blocked by mq.
595 # a partially completed rebase is blocked by mq.
606 if 'qtip' in repo.tags() and (dest.node() in
596 if 'qtip' in repo.tags() and (dest.node() in
607 [s.node for s in repo.mq.applied]):
597 [s.node for s in repo.mq.applied]):
608 raise util.Abort(_('cannot rebase onto an applied mq patch'))
598 raise util.Abort(_('cannot rebase onto an applied mq patch'))
609
599
610 detachset = set()
611 roots = list(repo.set('roots(%ld)', rebaseset))
600 roots = list(repo.set('roots(%ld)', rebaseset))
612 if not roots:
601 if not roots:
613 raise util.Abort(_('no matching revisions'))
602 raise util.Abort(_('no matching revisions'))
614 if len(roots) > 1:
603 if len(roots) > 1:
615 raise util.Abort(_("can't rebase multiple roots"))
604 raise util.Abort(_("can't rebase multiple roots"))
616 root = roots[0]
605 root = roots[0]
617
606
618 commonbase = root.ancestor(dest)
607 commonbase = root.ancestor(dest)
619 if commonbase == root:
608 if commonbase == root:
620 raise util.Abort(_('source is ancestor of destination'))
609 raise util.Abort(_('source is ancestor of destination'))
621 if commonbase == dest:
610 if commonbase == dest:
622 samebranch = root.branch() == dest.branch()
611 samebranch = root.branch() == dest.branch()
623 if not collapse and samebranch and root in dest.children():
612 if not collapse and samebranch and root in dest.children():
624 repo.ui.debug('source is a child of destination\n')
613 repo.ui.debug('source is a child of destination\n')
625 return None
614 return None
626 # rebase on ancestor, force detach
627 detach = True
628 if detach:
629 detachset = repo.revs('::%d - ::%d - %d', root, commonbase, root)
630
615
631 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, root))
616 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, root))
632 state = dict.fromkeys(rebaseset, nullrev)
617 state = dict.fromkeys(rebaseset, nullrev)
633 state.update(dict.fromkeys(detachset, nullmerge))
618 # Rebase tries to turn <dest> into a parent of <root> while
619 # preserving the number of parents of rebased changesets:
620 #
621 # - A changeset with a single parent will always be rebased as a
622 # changeset with a single parent.
623 #
624 # - A merge will be rebased as merge unless its parents are both
625 # ancestors of <dest> or are themselves in the rebased set and
626 # pruned while rebased.
627 #
628 # If one parent of <root> is an ancestor of <dest>, the rebased
629 # version of this parent will be <dest>. This is always true with
630 # --base option.
631 #
632 # Otherwise, we need to *replace* the original parents with
633 # <dest>. This "detaches" the rebased set from its former location
634 # and rebases it onto <dest>. Changes introduced by ancestors of
635 # <root> not common with <dest> (the detachset, marked as
636 # nullmerge) are "removed" from the rebased changesets.
637 #
638 # - If <root> has a single parent, set it to <dest>.
639 #
640 # - If <root> is a merge, we cannot decide which parent to
641 # replace, the rebase operation is not clearly defined.
642 #
643 # The table below sums up this behavior:
644 #
645 # +--------------------+----------------------+-------------------------+
646 # | | one parent | merge |
647 # +--------------------+----------------------+-------------------------+
648 # | parent in ::<dest> | new parent is <dest> | parents in ::<dest> are |
649 # | | | remapped to <dest> |
650 # +--------------------+----------------------+-------------------------+
651 # | unrelated source | new parent is <dest> | ambiguous, abort |
652 # +--------------------+----------------------+-------------------------+
653 #
654 # The actual abort is handled by `defineparents`
655 if len(root.parents()) <= 1:
656 # (strict) ancestors of <root> not ancestors of <dest>
657 detachset = repo.revs('::%d - ::%d - %d', root, commonbase, root)
658 state.update(dict.fromkeys(detachset, nullmerge))
634 return repo['.'].rev(), dest.rev(), state
659 return repo['.'].rev(), dest.rev(), state
635
660
636 def pullrebase(orig, ui, repo, *args, **opts):
661 def pullrebase(orig, ui, repo, *args, **opts):
637 'Call rebase after pull if the latter has been invoked with --rebase'
662 'Call rebase after pull if the latter has been invoked with --rebase'
638 if opts.get('rebase'):
663 if opts.get('rebase'):
639 if opts.get('update'):
664 if opts.get('update'):
640 del opts['update']
665 del opts['update']
641 ui.debug('--update and --rebase are not compatible, ignoring '
666 ui.debug('--update and --rebase are not compatible, ignoring '
642 'the update flag\n')
667 'the update flag\n')
643
668
644 movemarkfrom = repo['.'].node()
669 movemarkfrom = repo['.'].node()
645 cmdutil.bailifchanged(repo)
670 cmdutil.bailifchanged(repo)
646 revsprepull = len(repo)
671 revsprepull = len(repo)
647 origpostincoming = commands.postincoming
672 origpostincoming = commands.postincoming
648 def _dummy(*args, **kwargs):
673 def _dummy(*args, **kwargs):
649 pass
674 pass
650 commands.postincoming = _dummy
675 commands.postincoming = _dummy
651 try:
676 try:
652 orig(ui, repo, *args, **opts)
677 orig(ui, repo, *args, **opts)
653 finally:
678 finally:
654 commands.postincoming = origpostincoming
679 commands.postincoming = origpostincoming
655 revspostpull = len(repo)
680 revspostpull = len(repo)
656 if revspostpull > revsprepull:
681 if revspostpull > revsprepull:
657 rebase(ui, repo, **opts)
682 rebase(ui, repo, **opts)
658 branch = repo[None].branch()
683 branch = repo[None].branch()
659 dest = repo[branch].rev()
684 dest = repo[branch].rev()
660 if dest != repo['.'].rev():
685 if dest != repo['.'].rev():
661 # there was nothing to rebase we force an update
686 # there was nothing to rebase we force an update
662 hg.update(repo, dest)
687 hg.update(repo, dest)
663 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
688 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
664 ui.status(_("updating bookmark %s\n")
689 ui.status(_("updating bookmark %s\n")
665 % repo._bookmarkcurrent)
690 % repo._bookmarkcurrent)
666 else:
691 else:
667 if opts.get('tool'):
692 if opts.get('tool'):
668 raise util.Abort(_('--tool can only be used with --rebase'))
693 raise util.Abort(_('--tool can only be used with --rebase'))
669 orig(ui, repo, *args, **opts)
694 orig(ui, repo, *args, **opts)
670
695
671 def uisetup(ui):
696 def uisetup(ui):
672 'Replace pull with a decorator to provide --rebase option'
697 'Replace pull with a decorator to provide --rebase option'
673 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
698 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
674 entry[1].append(('', 'rebase', None,
699 entry[1].append(('', 'rebase', None,
675 _("rebase working directory to branch head")))
700 _("rebase working directory to branch head")))
676 entry[1].append(('t', 'tool', '',
701 entry[1].append(('t', 'tool', '',
677 _("specify merge tool for rebase")))
702 _("specify merge tool for rebase")))
@@ -1,67 +1,66 b''
1 $ echo "[extensions]" >> $HGRCPATH
1 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "rebase=" >> $HGRCPATH
2 $ echo "rebase=" >> $HGRCPATH
3
3
4 initialize repository
4 initialize repository
5
5
6 $ hg init
6 $ hg init
7
7
8 $ echo 'a' > a
8 $ echo 'a' > a
9 $ hg ci -A -m "0"
9 $ hg ci -A -m "0"
10 adding a
10 adding a
11
11
12 $ echo 'b' > b
12 $ echo 'b' > b
13 $ hg ci -A -m "1"
13 $ hg ci -A -m "1"
14 adding b
14 adding b
15
15
16 $ hg up 0
16 $ hg up 0
17 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
17 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
18 $ echo 'c' > c
18 $ echo 'c' > c
19 $ hg ci -A -m "2"
19 $ hg ci -A -m "2"
20 adding c
20 adding c
21 created new head
21 created new head
22
22
23 $ echo 'd' > d
23 $ echo 'd' > d
24 $ hg ci -A -m "3"
24 $ hg ci -A -m "3"
25 adding d
25 adding d
26
26
27 $ hg bookmark -r 1 one
27 $ hg bookmark -r 1 one
28 $ hg bookmark -r 3 two
28 $ hg bookmark -r 3 two
29
29
30 bookmark list
30 bookmark list
31
31
32 $ hg bookmark
32 $ hg bookmark
33 one 1:925d80f479bb
33 one 1:925d80f479bb
34 * two 3:2ae46b1d99a7
34 * two 3:2ae46b1d99a7
35
35
36 rebase
36 rebase
37
37
38 $ hg rebase -s two -d one
38 $ hg rebase -s two -d one
39 saved backup bundle to $TESTTMP/.hg/strip-backup/*-backup.hg (glob)
39 saved backup bundle to $TESTTMP/.hg/strip-backup/*-backup.hg (glob)
40
40
41 $ hg log
41 $ hg log
42 changeset: 3:9163974d1cb5
42 changeset: 3:42e5ed2cdcf4
43 bookmark: two
43 bookmark: two
44 tag: tip
44 tag: tip
45 parent: 1:925d80f479bb
45 parent: 1:925d80f479bb
46 parent: 2:db815d6d32e6
47 user: test
46 user: test
48 date: Thu Jan 01 00:00:00 1970 +0000
47 date: Thu Jan 01 00:00:00 1970 +0000
49 summary: 3
48 summary: 3
50
49
51 changeset: 2:db815d6d32e6
50 changeset: 2:db815d6d32e6
52 parent: 0:f7b1eb17ad24
51 parent: 0:f7b1eb17ad24
53 user: test
52 user: test
54 date: Thu Jan 01 00:00:00 1970 +0000
53 date: Thu Jan 01 00:00:00 1970 +0000
55 summary: 2
54 summary: 2
56
55
57 changeset: 1:925d80f479bb
56 changeset: 1:925d80f479bb
58 bookmark: one
57 bookmark: one
59 user: test
58 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
59 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: 1
60 summary: 1
62
61
63 changeset: 0:f7b1eb17ad24
62 changeset: 0:f7b1eb17ad24
64 user: test
63 user: test
65 date: Thu Jan 01 00:00:00 1970 +0000
64 date: Thu Jan 01 00:00:00 1970 +0000
66 summary: 0
65 summary: 0
67
66
@@ -1,90 +1,90 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 >
8 >
9 > [alias]
9 > [alias]
10 > tglog = log -G --template "{rev}: '{desc}' bookmarks: {bookmarks}\n"
10 > tglog = log -G --template "{rev}: '{desc}' bookmarks: {bookmarks}\n"
11 > EOF
11 > EOF
12
12
13 Create a repo with several bookmarks
13 Create a repo with several bookmarks
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16
16
17 $ echo a > a
17 $ echo a > a
18 $ hg ci -Am A
18 $ hg ci -Am A
19 adding a
19 adding a
20
20
21 $ echo b > b
21 $ echo b > b
22 $ hg ci -Am B
22 $ hg ci -Am B
23 adding b
23 adding b
24 $ hg book 'X'
24 $ hg book 'X'
25 $ hg book 'Y'
25 $ hg book 'Y'
26
26
27 $ echo c > c
27 $ echo c > c
28 $ hg ci -Am C
28 $ hg ci -Am C
29 adding c
29 adding c
30 $ hg book 'Z'
30 $ hg book 'Z'
31
31
32 $ hg up -q 0
32 $ hg up -q 0
33
33
34 $ echo d > d
34 $ echo d > d
35 $ hg ci -Am D
35 $ hg ci -Am D
36 adding d
36 adding d
37 created new head
37 created new head
38
38
39 $ hg tglog
39 $ hg tglog
40 @ 3: 'D' bookmarks:
40 @ 3: 'D' bookmarks:
41 |
41 |
42 | o 2: 'C' bookmarks: Y Z
42 | o 2: 'C' bookmarks: Y Z
43 | |
43 | |
44 | o 1: 'B' bookmarks: X
44 | o 1: 'B' bookmarks: X
45 |/
45 |/
46 o 0: 'A' bookmarks:
46 o 0: 'A' bookmarks:
47
47
48
48
49 Move only rebased bookmarks
49 Move only rebased bookmarks
50
50
51 $ cd ..
51 $ cd ..
52 $ hg clone -q a a1
52 $ hg clone -q a a1
53
53
54 $ cd a1
54 $ cd a1
55 $ hg up -q Z
55 $ hg up -q Z
56
56
57 $ hg rebase --detach -s Y -d 3
57 $ hg rebase -s Y -d 3
58 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
58 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
59
59
60 $ hg tglog
60 $ hg tglog
61 @ 3: 'C' bookmarks: Y Z
61 @ 3: 'C' bookmarks: Y Z
62 |
62 |
63 o 2: 'D' bookmarks:
63 o 2: 'D' bookmarks:
64 |
64 |
65 | o 1: 'B' bookmarks: X
65 | o 1: 'B' bookmarks: X
66 |/
66 |/
67 o 0: 'A' bookmarks:
67 o 0: 'A' bookmarks:
68
68
69 Keep bookmarks to the correct rebased changeset
69 Keep bookmarks to the correct rebased changeset
70
70
71 $ cd ..
71 $ cd ..
72 $ hg clone -q a a2
72 $ hg clone -q a a2
73
73
74 $ cd a2
74 $ cd a2
75 $ hg up -q Z
75 $ hg up -q Z
76
76
77 $ hg rebase -s 1 -d 3
77 $ hg rebase -s 1 -d 3
78 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
78 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
79
79
80 $ hg tglog
80 $ hg tglog
81 @ 3: 'C' bookmarks: Y Z
81 @ 3: 'C' bookmarks: Y Z
82 |
82 |
83 o 2: 'B' bookmarks: X
83 o 2: 'B' bookmarks: X
84 |
84 |
85 o 1: 'D' bookmarks:
85 o 1: 'D' bookmarks:
86 |
86 |
87 o 0: 'A' bookmarks:
87 o 0: 'A' bookmarks:
88
88
89
89
90 $ cd ..
90 $ cd ..
@@ -1,265 +1,265 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 >
8 >
9 > [alias]
9 > [alias]
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
11 > theads = heads --template "{rev}: '{desc}' {branches}\n"
11 > theads = heads --template "{rev}: '{desc}' {branches}\n"
12 > EOF
12 > EOF
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16
16
17 $ echo a > a
17 $ echo a > a
18 $ hg ci -Am A
18 $ hg ci -Am A
19 adding a
19 adding a
20
20
21 $ hg branch branch1
21 $ hg branch branch1
22 marked working directory as branch branch1
22 marked working directory as branch branch1
23 (branches are permanent and global, did you want a bookmark?)
23 (branches are permanent and global, did you want a bookmark?)
24 $ hg ci -m 'branch1'
24 $ hg ci -m 'branch1'
25
25
26 $ echo b > b
26 $ echo b > b
27 $ hg ci -Am B
27 $ hg ci -Am B
28 adding b
28 adding b
29
29
30 $ hg up -q 0
30 $ hg up -q 0
31
31
32 $ hg branch branch2
32 $ hg branch branch2
33 marked working directory as branch branch2
33 marked working directory as branch branch2
34 (branches are permanent and global, did you want a bookmark?)
34 (branches are permanent and global, did you want a bookmark?)
35 $ hg ci -m 'branch2'
35 $ hg ci -m 'branch2'
36
36
37 $ echo c > C
37 $ echo c > C
38 $ hg ci -Am C
38 $ hg ci -Am C
39 adding C
39 adding C
40
40
41 $ hg up -q 2
41 $ hg up -q 2
42
42
43 $ hg branch -f branch2
43 $ hg branch -f branch2
44 marked working directory as branch branch2
44 marked working directory as branch branch2
45 (branches are permanent and global, did you want a bookmark?)
45 (branches are permanent and global, did you want a bookmark?)
46 $ echo d > d
46 $ echo d > d
47 $ hg ci -Am D
47 $ hg ci -Am D
48 adding d
48 adding d
49 created new head
49 created new head
50
50
51 $ echo e > e
51 $ echo e > e
52 $ hg ci -Am E
52 $ hg ci -Am E
53 adding e
53 adding e
54
54
55 $ hg update default
55 $ hg update default
56 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
56 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
57
57
58 $ hg branch branch3
58 $ hg branch branch3
59 marked working directory as branch branch3
59 marked working directory as branch branch3
60 (branches are permanent and global, did you want a bookmark?)
60 (branches are permanent and global, did you want a bookmark?)
61 $ hg ci -m 'branch3'
61 $ hg ci -m 'branch3'
62
62
63 $ echo f > f
63 $ echo f > f
64 $ hg ci -Am F
64 $ hg ci -Am F
65 adding f
65 adding f
66
66
67 $ cd ..
67 $ cd ..
68
68
69
69
70 Rebase part of branch2 (5-6) onto branch3 (8):
70 Rebase part of branch2 (5-6) onto branch3 (8):
71
71
72 $ hg clone -q -u . a a1
72 $ hg clone -q -u . a a1
73 $ cd a1
73 $ cd a1
74
74
75 $ hg tglog
75 $ hg tglog
76 @ 8: 'F' branch3
76 @ 8: 'F' branch3
77 |
77 |
78 o 7: 'branch3' branch3
78 o 7: 'branch3' branch3
79 |
79 |
80 | o 6: 'E' branch2
80 | o 6: 'E' branch2
81 | |
81 | |
82 | o 5: 'D' branch2
82 | o 5: 'D' branch2
83 | |
83 | |
84 | | o 4: 'C' branch2
84 | | o 4: 'C' branch2
85 | | |
85 | | |
86 +---o 3: 'branch2' branch2
86 +---o 3: 'branch2' branch2
87 | |
87 | |
88 | o 2: 'B' branch1
88 | o 2: 'B' branch1
89 | |
89 | |
90 | o 1: 'branch1' branch1
90 | o 1: 'branch1' branch1
91 |/
91 |/
92 o 0: 'A'
92 o 0: 'A'
93
93
94 $ hg branches
94 $ hg branches
95 branch3 8:4666b71e8e32
95 branch3 8:4666b71e8e32
96 branch2 6:5097051d331d
96 branch2 6:5097051d331d
97 branch1 2:0a03079c47fd (inactive)
97 branch1 2:0a03079c47fd (inactive)
98 default 0:1994f17a630e (inactive)
98 default 0:1994f17a630e (inactive)
99
99
100 $ hg theads
100 $ hg theads
101 8: 'F' branch3
101 8: 'F' branch3
102 6: 'E' branch2
102 6: 'E' branch2
103 4: 'C' branch2
103 4: 'C' branch2
104 2: 'B' branch1
104 2: 'B' branch1
105 0: 'A'
105 0: 'A'
106
106
107 $ hg rebase --detach -s 5 -d 8
107 $ hg rebase -s 5 -d 8
108 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
108 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
109
109
110 $ hg branches
110 $ hg branches
111 branch3 8:466cdfb14b62
111 branch3 8:466cdfb14b62
112 branch2 4:e4fdb121d036
112 branch2 4:e4fdb121d036
113 branch1 2:0a03079c47fd
113 branch1 2:0a03079c47fd
114 default 0:1994f17a630e (inactive)
114 default 0:1994f17a630e (inactive)
115
115
116 $ hg theads
116 $ hg theads
117 8: 'E' branch3
117 8: 'E' branch3
118 4: 'C' branch2
118 4: 'C' branch2
119 2: 'B' branch1
119 2: 'B' branch1
120 0: 'A'
120 0: 'A'
121
121
122 $ hg tglog
122 $ hg tglog
123 @ 8: 'E' branch3
123 @ 8: 'E' branch3
124 |
124 |
125 o 7: 'D' branch3
125 o 7: 'D' branch3
126 |
126 |
127 o 6: 'F' branch3
127 o 6: 'F' branch3
128 |
128 |
129 o 5: 'branch3' branch3
129 o 5: 'branch3' branch3
130 |
130 |
131 | o 4: 'C' branch2
131 | o 4: 'C' branch2
132 | |
132 | |
133 | o 3: 'branch2' branch2
133 | o 3: 'branch2' branch2
134 |/
134 |/
135 | o 2: 'B' branch1
135 | o 2: 'B' branch1
136 | |
136 | |
137 | o 1: 'branch1' branch1
137 | o 1: 'branch1' branch1
138 |/
138 |/
139 o 0: 'A'
139 o 0: 'A'
140
140
141 $ cd ..
141 $ cd ..
142
142
143
143
144 Rebase head of branch3 (8) onto branch2 (6):
144 Rebase head of branch3 (8) onto branch2 (6):
145
145
146 $ hg clone -q -u . a a2
146 $ hg clone -q -u . a a2
147 $ cd a2
147 $ cd a2
148
148
149 $ hg tglog
149 $ hg tglog
150 @ 8: 'F' branch3
150 @ 8: 'F' branch3
151 |
151 |
152 o 7: 'branch3' branch3
152 o 7: 'branch3' branch3
153 |
153 |
154 | o 6: 'E' branch2
154 | o 6: 'E' branch2
155 | |
155 | |
156 | o 5: 'D' branch2
156 | o 5: 'D' branch2
157 | |
157 | |
158 | | o 4: 'C' branch2
158 | | o 4: 'C' branch2
159 | | |
159 | | |
160 +---o 3: 'branch2' branch2
160 +---o 3: 'branch2' branch2
161 | |
161 | |
162 | o 2: 'B' branch1
162 | o 2: 'B' branch1
163 | |
163 | |
164 | o 1: 'branch1' branch1
164 | o 1: 'branch1' branch1
165 |/
165 |/
166 o 0: 'A'
166 o 0: 'A'
167
167
168 $ hg rebase --detach -s 8 -d 6
168 $ hg rebase -s 8 -d 6
169 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
169 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
170
170
171 $ hg branches
171 $ hg branches
172 branch2 8:6b4bdc1b5ac0
172 branch2 8:6b4bdc1b5ac0
173 branch3 7:653b9feb4616
173 branch3 7:653b9feb4616
174 branch1 2:0a03079c47fd (inactive)
174 branch1 2:0a03079c47fd (inactive)
175 default 0:1994f17a630e (inactive)
175 default 0:1994f17a630e (inactive)
176
176
177 $ hg theads
177 $ hg theads
178 8: 'F' branch2
178 8: 'F' branch2
179 7: 'branch3' branch3
179 7: 'branch3' branch3
180 4: 'C' branch2
180 4: 'C' branch2
181 2: 'B' branch1
181 2: 'B' branch1
182 0: 'A'
182 0: 'A'
183
183
184 $ hg tglog
184 $ hg tglog
185 @ 8: 'F' branch2
185 @ 8: 'F' branch2
186 |
186 |
187 | o 7: 'branch3' branch3
187 | o 7: 'branch3' branch3
188 | |
188 | |
189 o | 6: 'E' branch2
189 o | 6: 'E' branch2
190 | |
190 | |
191 o | 5: 'D' branch2
191 o | 5: 'D' branch2
192 | |
192 | |
193 | | o 4: 'C' branch2
193 | | o 4: 'C' branch2
194 | | |
194 | | |
195 | | o 3: 'branch2' branch2
195 | | o 3: 'branch2' branch2
196 | |/
196 | |/
197 o | 2: 'B' branch1
197 o | 2: 'B' branch1
198 | |
198 | |
199 o | 1: 'branch1' branch1
199 o | 1: 'branch1' branch1
200 |/
200 |/
201 o 0: 'A'
201 o 0: 'A'
202
202
203 $ hg verify -q
203 $ hg verify -q
204
204
205 $ cd ..
205 $ cd ..
206
206
207
207
208 Rebase entire branch3 (7-8) onto branch2 (6):
208 Rebase entire branch3 (7-8) onto branch2 (6):
209
209
210 $ hg clone -q -u . a a3
210 $ hg clone -q -u . a a3
211 $ cd a3
211 $ cd a3
212
212
213 $ hg tglog
213 $ hg tglog
214 @ 8: 'F' branch3
214 @ 8: 'F' branch3
215 |
215 |
216 o 7: 'branch3' branch3
216 o 7: 'branch3' branch3
217 |
217 |
218 | o 6: 'E' branch2
218 | o 6: 'E' branch2
219 | |
219 | |
220 | o 5: 'D' branch2
220 | o 5: 'D' branch2
221 | |
221 | |
222 | | o 4: 'C' branch2
222 | | o 4: 'C' branch2
223 | | |
223 | | |
224 +---o 3: 'branch2' branch2
224 +---o 3: 'branch2' branch2
225 | |
225 | |
226 | o 2: 'B' branch1
226 | o 2: 'B' branch1
227 | |
227 | |
228 | o 1: 'branch1' branch1
228 | o 1: 'branch1' branch1
229 |/
229 |/
230 o 0: 'A'
230 o 0: 'A'
231
231
232 $ hg rebase --detach -s 7 -d 6
232 $ hg rebase -s 7 -d 6
233 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
233 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
234
234
235 $ hg branches
235 $ hg branches
236 branch2 7:6b4bdc1b5ac0
236 branch2 7:6b4bdc1b5ac0
237 branch1 2:0a03079c47fd (inactive)
237 branch1 2:0a03079c47fd (inactive)
238 default 0:1994f17a630e (inactive)
238 default 0:1994f17a630e (inactive)
239
239
240 $ hg theads
240 $ hg theads
241 7: 'F' branch2
241 7: 'F' branch2
242 4: 'C' branch2
242 4: 'C' branch2
243 2: 'B' branch1
243 2: 'B' branch1
244 0: 'A'
244 0: 'A'
245
245
246 $ hg tglog
246 $ hg tglog
247 @ 7: 'F' branch2
247 @ 7: 'F' branch2
248 |
248 |
249 o 6: 'E' branch2
249 o 6: 'E' branch2
250 |
250 |
251 o 5: 'D' branch2
251 o 5: 'D' branch2
252 |
252 |
253 | o 4: 'C' branch2
253 | o 4: 'C' branch2
254 | |
254 | |
255 | o 3: 'branch2' branch2
255 | o 3: 'branch2' branch2
256 | |
256 | |
257 o | 2: 'B' branch1
257 o | 2: 'B' branch1
258 | |
258 | |
259 o | 1: 'branch1' branch1
259 o | 1: 'branch1' branch1
260 |/
260 |/
261 o 0: 'A'
261 o 0: 'A'
262
262
263 $ hg verify -q
263 $ hg verify -q
264
264
265 $ cd ..
265 $ cd ..
@@ -1,632 +1,630 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 >
8 >
9 > [alias]
9 > [alias]
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
11 > tglogp = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
11 > tglogp = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
12 > EOF
12 > EOF
13
13
14 Create repo a:
14 Create repo a:
15
15
16 $ hg init a
16 $ hg init a
17 $ cd a
17 $ cd a
18 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
18 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
19 adding changesets
19 adding changesets
20 adding manifests
20 adding manifests
21 adding file changes
21 adding file changes
22 added 8 changesets with 7 changes to 7 files (+2 heads)
22 added 8 changesets with 7 changes to 7 files (+2 heads)
23 (run 'hg heads' to see heads, 'hg merge' to merge)
23 (run 'hg heads' to see heads, 'hg merge' to merge)
24 $ hg up tip
24 $ hg up tip
25 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
26
26
27 $ hg tglog
27 $ hg tglog
28 @ 7: 'H'
28 @ 7: 'H'
29 |
29 |
30 | o 6: 'G'
30 | o 6: 'G'
31 |/|
31 |/|
32 o | 5: 'F'
32 o | 5: 'F'
33 | |
33 | |
34 | o 4: 'E'
34 | o 4: 'E'
35 |/
35 |/
36 | o 3: 'D'
36 | o 3: 'D'
37 | |
37 | |
38 | o 2: 'C'
38 | o 2: 'C'
39 | |
39 | |
40 | o 1: 'B'
40 | o 1: 'B'
41 |/
41 |/
42 o 0: 'A'
42 o 0: 'A'
43
43
44 $ cd ..
44 $ cd ..
45
45
46
46
47 Rebasing B onto H and collapsing changesets with different phases:
47 Rebasing B onto H and collapsing changesets with different phases:
48
48
49
49
50 $ hg clone -q -u 3 a a1
50 $ hg clone -q -u 3 a a1
51 $ cd a1
51 $ cd a1
52
52
53 $ hg phase --force --secret 3
53 $ hg phase --force --secret 3
54
54
55 $ hg rebase --collapse --keepbranches
55 $ hg rebase --collapse --keepbranches
56 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
56 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
57
57
58 $ hg tglogp
58 $ hg tglogp
59 @ 5:secret 'Collapsed revision
59 @ 5:secret 'Collapsed revision
60 | * B
60 | * B
61 | * C
61 | * C
62 | * D'
62 | * D'
63 o 4:draft 'H'
63 o 4:draft 'H'
64 |
64 |
65 | o 3:draft 'G'
65 | o 3:draft 'G'
66 |/|
66 |/|
67 o | 2:draft 'F'
67 o | 2:draft 'F'
68 | |
68 | |
69 | o 1:draft 'E'
69 | o 1:draft 'E'
70 |/
70 |/
71 o 0:draft 'A'
71 o 0:draft 'A'
72
72
73 $ hg manifest
73 $ hg manifest
74 A
74 A
75 B
75 B
76 C
76 C
77 D
77 D
78 F
78 F
79 H
79 H
80
80
81 $ cd ..
81 $ cd ..
82
82
83
83
84 Rebasing E onto H:
84 Rebasing E onto H:
85
85
86 $ hg clone -q -u . a a2
86 $ hg clone -q -u . a a2
87 $ cd a2
87 $ cd a2
88
88
89 $ hg phase --force --secret 6
89 $ hg phase --force --secret 6
90 $ hg rebase --source 4 --collapse
90 $ hg rebase --source 4 --collapse
91 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
91 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
92
92
93 $ hg tglog
93 $ hg tglog
94 @ 6: 'Collapsed revision
94 @ 6: 'Collapsed revision
95 | * E
95 | * E
96 | * G'
96 | * G'
97 o 5: 'H'
97 o 5: 'H'
98 |
98 |
99 o 4: 'F'
99 o 4: 'F'
100 |
100 |
101 | o 3: 'D'
101 | o 3: 'D'
102 | |
102 | |
103 | o 2: 'C'
103 | o 2: 'C'
104 | |
104 | |
105 | o 1: 'B'
105 | o 1: 'B'
106 |/
106 |/
107 o 0: 'A'
107 o 0: 'A'
108
108
109 $ hg manifest
109 $ hg manifest
110 A
110 A
111 E
111 E
112 F
112 F
113 H
113 H
114
114
115 $ cd ..
115 $ cd ..
116
116
117 Rebasing G onto H with custom message:
117 Rebasing G onto H with custom message:
118
118
119 $ hg clone -q -u . a a3
119 $ hg clone -q -u . a a3
120 $ cd a3
120 $ cd a3
121
121
122 $ hg rebase --base 6 -m 'custom message'
122 $ hg rebase --base 6 -m 'custom message'
123 abort: message can only be specified with collapse
123 abort: message can only be specified with collapse
124 [255]
124 [255]
125
125
126 $ hg rebase --source 4 --collapse -m 'custom message'
126 $ hg rebase --source 4 --collapse -m 'custom message'
127 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
127 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
128
128
129 $ hg tglog
129 $ hg tglog
130 @ 6: 'custom message'
130 @ 6: 'custom message'
131 |
131 |
132 o 5: 'H'
132 o 5: 'H'
133 |
133 |
134 o 4: 'F'
134 o 4: 'F'
135 |
135 |
136 | o 3: 'D'
136 | o 3: 'D'
137 | |
137 | |
138 | o 2: 'C'
138 | o 2: 'C'
139 | |
139 | |
140 | o 1: 'B'
140 | o 1: 'B'
141 |/
141 |/
142 o 0: 'A'
142 o 0: 'A'
143
143
144 $ hg manifest
144 $ hg manifest
145 A
145 A
146 E
146 E
147 F
147 F
148 H
148 H
149
149
150 $ cd ..
150 $ cd ..
151
151
152 Create repo b:
152 Create repo b:
153
153
154 $ hg init b
154 $ hg init b
155 $ cd b
155 $ cd b
156
156
157 $ echo A > A
157 $ echo A > A
158 $ hg ci -Am A
158 $ hg ci -Am A
159 adding A
159 adding A
160 $ echo B > B
160 $ echo B > B
161 $ hg ci -Am B
161 $ hg ci -Am B
162 adding B
162 adding B
163
163
164 $ hg up -q 0
164 $ hg up -q 0
165
165
166 $ echo C > C
166 $ echo C > C
167 $ hg ci -Am C
167 $ hg ci -Am C
168 adding C
168 adding C
169 created new head
169 created new head
170
170
171 $ hg merge
171 $ hg merge
172 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
172 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 (branch merge, don't forget to commit)
173 (branch merge, don't forget to commit)
174
174
175 $ echo D > D
175 $ echo D > D
176 $ hg ci -Am D
176 $ hg ci -Am D
177 adding D
177 adding D
178
178
179 $ hg up -q 1
179 $ hg up -q 1
180
180
181 $ echo E > E
181 $ echo E > E
182 $ hg ci -Am E
182 $ hg ci -Am E
183 adding E
183 adding E
184 created new head
184 created new head
185
185
186 $ echo F > F
186 $ echo F > F
187 $ hg ci -Am F
187 $ hg ci -Am F
188 adding F
188 adding F
189
189
190 $ hg merge
190 $ hg merge
191 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 (branch merge, don't forget to commit)
192 (branch merge, don't forget to commit)
193 $ hg ci -m G
193 $ hg ci -m G
194
194
195 $ hg up -q 0
195 $ hg up -q 0
196
196
197 $ echo H > H
197 $ echo H > H
198 $ hg ci -Am H
198 $ hg ci -Am H
199 adding H
199 adding H
200 created new head
200 created new head
201
201
202 $ hg tglog
202 $ hg tglog
203 @ 7: 'H'
203 @ 7: 'H'
204 |
204 |
205 | o 6: 'G'
205 | o 6: 'G'
206 | |\
206 | |\
207 | | o 5: 'F'
207 | | o 5: 'F'
208 | | |
208 | | |
209 | | o 4: 'E'
209 | | o 4: 'E'
210 | | |
210 | | |
211 | o | 3: 'D'
211 | o | 3: 'D'
212 | |\|
212 | |\|
213 | o | 2: 'C'
213 | o | 2: 'C'
214 |/ /
214 |/ /
215 | o 1: 'B'
215 | o 1: 'B'
216 |/
216 |/
217 o 0: 'A'
217 o 0: 'A'
218
218
219 $ cd ..
219 $ cd ..
220
220
221
221
222 Rebase and collapse - more than one external (fail):
222 Rebase and collapse - more than one external (fail):
223
223
224 $ hg clone -q -u . b b1
224 $ hg clone -q -u . b b1
225 $ cd b1
225 $ cd b1
226
226
227 $ hg rebase -s 2 --collapse
227 $ hg rebase -s 2 --collapse
228 abort: unable to collapse, there is more than one external parent
228 abort: unable to collapse, there is more than one external parent
229 [255]
229 [255]
230
230
231 Rebase and collapse - E onto H:
231 Rebase and collapse - E onto H:
232
232
233 $ hg rebase -s 4 --collapse
233 $ hg rebase -s 4 --collapse # root (4) is not a merge
234 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
234 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
235
235
236 $ hg tglog
236 $ hg tglog
237 @ 5: 'Collapsed revision
237 @ 5: 'Collapsed revision
238 |\ * E
238 |\ * E
239 | | * F
239 | | * F
240 | | * G'
240 | | * G'
241 | o 4: 'H'
241 | o 4: 'H'
242 | |
242 | |
243 o | 3: 'D'
243 o | 3: 'D'
244 |\ \
244 |\ \
245 | o | 2: 'C'
245 | o | 2: 'C'
246 | |/
246 | |/
247 o / 1: 'B'
247 o / 1: 'B'
248 |/
248 |/
249 o 0: 'A'
249 o 0: 'A'
250
250
251 $ hg manifest
251 $ hg manifest
252 A
252 A
253 B
254 C
253 C
255 D
254 D
256 E
255 E
257 F
256 F
258 H
257 H
259
258
260 $ cd ..
259 $ cd ..
261
260
262
261
263 Create repo c:
262 Create repo c:
264
263
265 $ hg init c
264 $ hg init c
266 $ cd c
265 $ cd c
267
266
268 $ echo A > A
267 $ echo A > A
269 $ hg ci -Am A
268 $ hg ci -Am A
270 adding A
269 adding A
271 $ echo B > B
270 $ echo B > B
272 $ hg ci -Am B
271 $ hg ci -Am B
273 adding B
272 adding B
274
273
275 $ hg up -q 0
274 $ hg up -q 0
276
275
277 $ echo C > C
276 $ echo C > C
278 $ hg ci -Am C
277 $ hg ci -Am C
279 adding C
278 adding C
280 created new head
279 created new head
281
280
282 $ hg merge
281 $ hg merge
283 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
282 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 (branch merge, don't forget to commit)
283 (branch merge, don't forget to commit)
285
284
286 $ echo D > D
285 $ echo D > D
287 $ hg ci -Am D
286 $ hg ci -Am D
288 adding D
287 adding D
289
288
290 $ hg up -q 1
289 $ hg up -q 1
291
290
292 $ echo E > E
291 $ echo E > E
293 $ hg ci -Am E
292 $ hg ci -Am E
294 adding E
293 adding E
295 created new head
294 created new head
296 $ echo F > E
295 $ echo F > E
297 $ hg ci -m 'F'
296 $ hg ci -m 'F'
298
297
299 $ echo G > G
298 $ echo G > G
300 $ hg ci -Am G
299 $ hg ci -Am G
301 adding G
300 adding G
302
301
303 $ hg merge
302 $ hg merge
304 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
303 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
305 (branch merge, don't forget to commit)
304 (branch merge, don't forget to commit)
306
305
307 $ hg ci -m H
306 $ hg ci -m H
308
307
309 $ hg up -q 0
308 $ hg up -q 0
310
309
311 $ echo I > I
310 $ echo I > I
312 $ hg ci -Am I
311 $ hg ci -Am I
313 adding I
312 adding I
314 created new head
313 created new head
315
314
316 $ hg tglog
315 $ hg tglog
317 @ 8: 'I'
316 @ 8: 'I'
318 |
317 |
319 | o 7: 'H'
318 | o 7: 'H'
320 | |\
319 | |\
321 | | o 6: 'G'
320 | | o 6: 'G'
322 | | |
321 | | |
323 | | o 5: 'F'
322 | | o 5: 'F'
324 | | |
323 | | |
325 | | o 4: 'E'
324 | | o 4: 'E'
326 | | |
325 | | |
327 | o | 3: 'D'
326 | o | 3: 'D'
328 | |\|
327 | |\|
329 | o | 2: 'C'
328 | o | 2: 'C'
330 |/ /
329 |/ /
331 | o 1: 'B'
330 | o 1: 'B'
332 |/
331 |/
333 o 0: 'A'
332 o 0: 'A'
334
333
335 $ cd ..
334 $ cd ..
336
335
337
336
338 Rebase and collapse - E onto I:
337 Rebase and collapse - E onto I:
339
338
340 $ hg clone -q -u . c c1
339 $ hg clone -q -u . c c1
341 $ cd c1
340 $ cd c1
342
341
343 $ hg rebase -s 4 --collapse
342 $ hg rebase -s 4 --collapse # root (4) is not a merge
344 merging E
343 merging E
345 saved backup bundle to $TESTTMP/c1/.hg/strip-backup/*-backup.hg (glob)
344 saved backup bundle to $TESTTMP/c1/.hg/strip-backup/*-backup.hg (glob)
346
345
347 $ hg tglog
346 $ hg tglog
348 @ 5: 'Collapsed revision
347 @ 5: 'Collapsed revision
349 |\ * E
348 |\ * E
350 | | * F
349 | | * F
351 | | * G
350 | | * G
352 | | * H'
351 | | * H'
353 | o 4: 'I'
352 | o 4: 'I'
354 | |
353 | |
355 o | 3: 'D'
354 o | 3: 'D'
356 |\ \
355 |\ \
357 | o | 2: 'C'
356 | o | 2: 'C'
358 | |/
357 | |/
359 o / 1: 'B'
358 o / 1: 'B'
360 |/
359 |/
361 o 0: 'A'
360 o 0: 'A'
362
361
363 $ hg manifest
362 $ hg manifest
364 A
363 A
365 B
366 C
364 C
367 D
365 D
368 E
366 E
369 G
367 G
370 I
368 I
371
369
372 $ cat E
370 $ cat E
373 F
371 F
374
372
375 $ cd ..
373 $ cd ..
376
374
377
375
378 Create repo d:
376 Create repo d:
379
377
380 $ hg init d
378 $ hg init d
381 $ cd d
379 $ cd d
382
380
383 $ echo A > A
381 $ echo A > A
384 $ hg ci -Am A
382 $ hg ci -Am A
385 adding A
383 adding A
386 $ echo B > B
384 $ echo B > B
387 $ hg ci -Am B
385 $ hg ci -Am B
388 adding B
386 adding B
389 $ echo C > C
387 $ echo C > C
390 $ hg ci -Am C
388 $ hg ci -Am C
391 adding C
389 adding C
392
390
393 $ hg up -q 1
391 $ hg up -q 1
394
392
395 $ echo D > D
393 $ echo D > D
396 $ hg ci -Am D
394 $ hg ci -Am D
397 adding D
395 adding D
398 created new head
396 created new head
399 $ hg merge
397 $ hg merge
400 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
401 (branch merge, don't forget to commit)
399 (branch merge, don't forget to commit)
402
400
403 $ hg ci -m E
401 $ hg ci -m E
404
402
405 $ hg up -q 0
403 $ hg up -q 0
406
404
407 $ echo F > F
405 $ echo F > F
408 $ hg ci -Am F
406 $ hg ci -Am F
409 adding F
407 adding F
410 created new head
408 created new head
411
409
412 $ hg tglog
410 $ hg tglog
413 @ 5: 'F'
411 @ 5: 'F'
414 |
412 |
415 | o 4: 'E'
413 | o 4: 'E'
416 | |\
414 | |\
417 | | o 3: 'D'
415 | | o 3: 'D'
418 | | |
416 | | |
419 | o | 2: 'C'
417 | o | 2: 'C'
420 | |/
418 | |/
421 | o 1: 'B'
419 | o 1: 'B'
422 |/
420 |/
423 o 0: 'A'
421 o 0: 'A'
424
422
425 $ cd ..
423 $ cd ..
426
424
427
425
428 Rebase and collapse - B onto F:
426 Rebase and collapse - B onto F:
429
427
430 $ hg clone -q -u . d d1
428 $ hg clone -q -u . d d1
431 $ cd d1
429 $ cd d1
432
430
433 $ hg rebase -s 1 --collapse
431 $ hg rebase -s 1 --collapse
434 saved backup bundle to $TESTTMP/d1/.hg/strip-backup/*-backup.hg (glob)
432 saved backup bundle to $TESTTMP/d1/.hg/strip-backup/*-backup.hg (glob)
435
433
436 $ hg tglog
434 $ hg tglog
437 @ 2: 'Collapsed revision
435 @ 2: 'Collapsed revision
438 | * B
436 | * B
439 | * C
437 | * C
440 | * D
438 | * D
441 | * E'
439 | * E'
442 o 1: 'F'
440 o 1: 'F'
443 |
441 |
444 o 0: 'A'
442 o 0: 'A'
445
443
446 $ hg manifest
444 $ hg manifest
447 A
445 A
448 B
446 B
449 C
447 C
450 D
448 D
451 F
449 F
452
450
453 Interactions between collapse and keepbranches
451 Interactions between collapse and keepbranches
454 $ cd ..
452 $ cd ..
455 $ hg init e
453 $ hg init e
456 $ cd e
454 $ cd e
457 $ echo 'a' > a
455 $ echo 'a' > a
458 $ hg ci -Am 'A'
456 $ hg ci -Am 'A'
459 adding a
457 adding a
460
458
461 $ hg branch '1'
459 $ hg branch '1'
462 marked working directory as branch 1
460 marked working directory as branch 1
463 (branches are permanent and global, did you want a bookmark?)
461 (branches are permanent and global, did you want a bookmark?)
464 $ echo 'b' > b
462 $ echo 'b' > b
465 $ hg ci -Am 'B'
463 $ hg ci -Am 'B'
466 adding b
464 adding b
467
465
468 $ hg branch '2'
466 $ hg branch '2'
469 marked working directory as branch 2
467 marked working directory as branch 2
470 (branches are permanent and global, did you want a bookmark?)
468 (branches are permanent and global, did you want a bookmark?)
471 $ echo 'c' > c
469 $ echo 'c' > c
472 $ hg ci -Am 'C'
470 $ hg ci -Am 'C'
473 adding c
471 adding c
474
472
475 $ hg up -q 0
473 $ hg up -q 0
476 $ echo 'd' > d
474 $ echo 'd' > d
477 $ hg ci -Am 'D'
475 $ hg ci -Am 'D'
478 adding d
476 adding d
479
477
480 $ hg tglog
478 $ hg tglog
481 @ 3: 'D'
479 @ 3: 'D'
482 |
480 |
483 | o 2: 'C' 2
481 | o 2: 'C' 2
484 | |
482 | |
485 | o 1: 'B' 1
483 | o 1: 'B' 1
486 |/
484 |/
487 o 0: 'A'
485 o 0: 'A'
488
486
489 $ hg rebase --keepbranches --collapse -s 1 -d 3
487 $ hg rebase --keepbranches --collapse -s 1 -d 3
490 abort: cannot collapse multiple named branches
488 abort: cannot collapse multiple named branches
491 [255]
489 [255]
492
490
493 $ repeatchange() {
491 $ repeatchange() {
494 > hg checkout $1
492 > hg checkout $1
495 > hg cp d z
493 > hg cp d z
496 > echo blah >> z
494 > echo blah >> z
497 > hg commit -Am "$2" --user "$3"
495 > hg commit -Am "$2" --user "$3"
498 > }
496 > }
499 $ repeatchange 3 "E" "user1"
497 $ repeatchange 3 "E" "user1"
500 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
501 $ repeatchange 3 "E" "user2"
499 $ repeatchange 3 "E" "user2"
502 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
500 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
503 created new head
501 created new head
504 $ hg tglog
502 $ hg tglog
505 @ 5: 'E'
503 @ 5: 'E'
506 |
504 |
507 | o 4: 'E'
505 | o 4: 'E'
508 |/
506 |/
509 o 3: 'D'
507 o 3: 'D'
510 |
508 |
511 | o 2: 'C' 2
509 | o 2: 'C' 2
512 | |
510 | |
513 | o 1: 'B' 1
511 | o 1: 'B' 1
514 |/
512 |/
515 o 0: 'A'
513 o 0: 'A'
516
514
517 $ hg rebase -s 5 -d 4
515 $ hg rebase -s 5 -d 4
518 saved backup bundle to $TESTTMP/e/.hg/strip-backup/*-backup.hg (glob)
516 saved backup bundle to $TESTTMP/e/.hg/strip-backup/*-backup.hg (glob)
519 $ hg tglog
517 $ hg tglog
520 @ 4: 'E'
518 @ 4: 'E'
521 |
519 |
522 o 3: 'D'
520 o 3: 'D'
523 |
521 |
524 | o 2: 'C' 2
522 | o 2: 'C' 2
525 | |
523 | |
526 | o 1: 'B' 1
524 | o 1: 'B' 1
527 |/
525 |/
528 o 0: 'A'
526 o 0: 'A'
529
527
530 $ hg export tip
528 $ hg export tip
531 # HG changeset patch
529 # HG changeset patch
532 # User user1
530 # User user1
533 # Date 0 0
531 # Date 0 0
534 # Node ID f338eb3c2c7cc5b5915676a2376ba7ac558c5213
532 # Node ID f338eb3c2c7cc5b5915676a2376ba7ac558c5213
535 # Parent 41acb9dca9eb976e84cd21fcb756b4afa5a35c09
533 # Parent 41acb9dca9eb976e84cd21fcb756b4afa5a35c09
536 E
534 E
537
535
538 diff -r 41acb9dca9eb -r f338eb3c2c7c z
536 diff -r 41acb9dca9eb -r f338eb3c2c7c z
539 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
537 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
540 +++ b/z Thu Jan 01 00:00:00 1970 +0000
538 +++ b/z Thu Jan 01 00:00:00 1970 +0000
541 @@ -0,0 +1,2 @@
539 @@ -0,0 +1,2 @@
542 +d
540 +d
543 +blah
541 +blah
544
542
545 $ cd ..
543 $ cd ..
546
544
547 Rebase, collapse and copies
545 Rebase, collapse and copies
548
546
549 $ hg init copies
547 $ hg init copies
550 $ cd copies
548 $ cd copies
551 $ hg unbundle "$TESTDIR/bundles/renames.hg"
549 $ hg unbundle "$TESTDIR/bundles/renames.hg"
552 adding changesets
550 adding changesets
553 adding manifests
551 adding manifests
554 adding file changes
552 adding file changes
555 added 4 changesets with 11 changes to 7 files (+1 heads)
553 added 4 changesets with 11 changes to 7 files (+1 heads)
556 (run 'hg heads' to see heads, 'hg merge' to merge)
554 (run 'hg heads' to see heads, 'hg merge' to merge)
557 $ hg up -q tip
555 $ hg up -q tip
558 $ hg tglog
556 $ hg tglog
559 @ 3: 'move2'
557 @ 3: 'move2'
560 |
558 |
561 o 2: 'move1'
559 o 2: 'move1'
562 |
560 |
563 | o 1: 'change'
561 | o 1: 'change'
564 |/
562 |/
565 o 0: 'add'
563 o 0: 'add'
566
564
567 $ hg rebase --collapse -d 1
565 $ hg rebase --collapse -d 1
568 merging a and d to d
566 merging a and d to d
569 merging b and e to e
567 merging b and e to e
570 merging c and f to f
568 merging c and f to f
571 merging e and g to g
569 merging e and g to g
572 merging f and c to c
570 merging f and c to c
573 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
571 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
574 $ hg st
572 $ hg st
575 $ hg st --copies --change .
573 $ hg st --copies --change .
576 A d
574 A d
577 a
575 a
578 A g
576 A g
579 b
577 b
580 R b
578 R b
581 $ cat c
579 $ cat c
582 c
580 c
583 c
581 c
584 $ cat d
582 $ cat d
585 a
583 a
586 a
584 a
587 $ cat g
585 $ cat g
588 b
586 b
589 b
587 b
590 $ hg log -r . --template "{file_copies}\n"
588 $ hg log -r . --template "{file_copies}\n"
591 d (a)g (b)
589 d (a)g (b)
592
590
593 Test collapsing a middle revision in-place
591 Test collapsing a middle revision in-place
594
592
595 $ hg tglog
593 $ hg tglog
596 @ 2: 'Collapsed revision
594 @ 2: 'Collapsed revision
597 | * move1
595 | * move1
598 | * move2'
596 | * move2'
599 o 1: 'change'
597 o 1: 'change'
600 |
598 |
601 o 0: 'add'
599 o 0: 'add'
602
600
603 $ hg rebase --collapse -r 1 -d 0
601 $ hg rebase --collapse -r 1 -d 0
604 abort: can't remove original changesets with unrebased descendants
602 abort: can't remove original changesets with unrebased descendants
605 (use --keep to keep original changesets)
603 (use --keep to keep original changesets)
606 [255]
604 [255]
607
605
608 Test collapsing in place
606 Test collapsing in place
609
607
610 $ hg rebase --collapse -b . -d 0
608 $ hg rebase --collapse -b . -d 0
611 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
609 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
612 $ hg st --change . --copies
610 $ hg st --change . --copies
613 M a
611 M a
614 M c
612 M c
615 A d
613 A d
616 a
614 a
617 A g
615 A g
618 b
616 b
619 R b
617 R b
620 $ cat a
618 $ cat a
621 a
619 a
622 a
620 a
623 $ cat c
621 $ cat c
624 c
622 c
625 c
623 c
626 $ cat d
624 $ cat d
627 a
625 a
628 a
626 a
629 $ cat g
627 $ cat g
630 b
628 b
631 b
629 b
632 $ cd ..
630 $ cd ..
@@ -1,400 +1,400 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 >
8 >
9 > [alias]
9 > [alias]
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
11 > EOF
11 > EOF
12
12
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
17 adding changesets
17 adding changesets
18 adding manifests
18 adding manifests
19 adding file changes
19 adding file changes
20 added 8 changesets with 7 changes to 7 files (+2 heads)
20 added 8 changesets with 7 changes to 7 files (+2 heads)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
22 $ hg up tip
22 $ hg up tip
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
24
24
25 $ cd ..
25 $ cd ..
26
26
27
27
28 Rebasing D onto H detaching from C:
28 Rebasing D onto H detaching from C:
29
29
30 $ hg clone -q -u . a a1
30 $ hg clone -q -u . a a1
31 $ cd a1
31 $ cd a1
32
32
33 $ hg tglog
33 $ hg tglog
34 @ 7: 'H'
34 @ 7: 'H'
35 |
35 |
36 | o 6: 'G'
36 | o 6: 'G'
37 |/|
37 |/|
38 o | 5: 'F'
38 o | 5: 'F'
39 | |
39 | |
40 | o 4: 'E'
40 | o 4: 'E'
41 |/
41 |/
42 | o 3: 'D'
42 | o 3: 'D'
43 | |
43 | |
44 | o 2: 'C'
44 | o 2: 'C'
45 | |
45 | |
46 | o 1: 'B'
46 | o 1: 'B'
47 |/
47 |/
48 o 0: 'A'
48 o 0: 'A'
49
49
50 $ hg phase --force --secret 3
50 $ hg phase --force --secret 3
51 $ hg rebase --detach -s 3 -d 7
51 $ hg rebase -s 3 -d 7
52 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
52 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
53
53
54 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
54 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
55 @ 7:secret 'D'
55 @ 7:secret 'D'
56 |
56 |
57 o 6:draft 'H'
57 o 6:draft 'H'
58 |
58 |
59 | o 5:draft 'G'
59 | o 5:draft 'G'
60 |/|
60 |/|
61 o | 4:draft 'F'
61 o | 4:draft 'F'
62 | |
62 | |
63 | o 3:draft 'E'
63 | o 3:draft 'E'
64 |/
64 |/
65 | o 2:draft 'C'
65 | o 2:draft 'C'
66 | |
66 | |
67 | o 1:draft 'B'
67 | o 1:draft 'B'
68 |/
68 |/
69 o 0:draft 'A'
69 o 0:draft 'A'
70
70
71 $ hg manifest
71 $ hg manifest
72 A
72 A
73 D
73 D
74 F
74 F
75 H
75 H
76
76
77 $ cd ..
77 $ cd ..
78
78
79
79
80 Rebasing C onto H detaching from B:
80 Rebasing C onto H detaching from B:
81
81
82 $ hg clone -q -u . a a2
82 $ hg clone -q -u . a a2
83 $ cd a2
83 $ cd a2
84
84
85 $ hg tglog
85 $ hg tglog
86 @ 7: 'H'
86 @ 7: 'H'
87 |
87 |
88 | o 6: 'G'
88 | o 6: 'G'
89 |/|
89 |/|
90 o | 5: 'F'
90 o | 5: 'F'
91 | |
91 | |
92 | o 4: 'E'
92 | o 4: 'E'
93 |/
93 |/
94 | o 3: 'D'
94 | o 3: 'D'
95 | |
95 | |
96 | o 2: 'C'
96 | o 2: 'C'
97 | |
97 | |
98 | o 1: 'B'
98 | o 1: 'B'
99 |/
99 |/
100 o 0: 'A'
100 o 0: 'A'
101
101
102 $ hg rebase --detach -s 2 -d 7
102 $ hg rebase -s 2 -d 7
103 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
103 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
104
104
105 $ hg tglog
105 $ hg tglog
106 @ 7: 'D'
106 @ 7: 'D'
107 |
107 |
108 o 6: 'C'
108 o 6: 'C'
109 |
109 |
110 o 5: 'H'
110 o 5: 'H'
111 |
111 |
112 | o 4: 'G'
112 | o 4: 'G'
113 |/|
113 |/|
114 o | 3: 'F'
114 o | 3: 'F'
115 | |
115 | |
116 | o 2: 'E'
116 | o 2: 'E'
117 |/
117 |/
118 | o 1: 'B'
118 | o 1: 'B'
119 |/
119 |/
120 o 0: 'A'
120 o 0: 'A'
121
121
122 $ hg manifest
122 $ hg manifest
123 A
123 A
124 C
124 C
125 D
125 D
126 F
126 F
127 H
127 H
128
128
129 $ cd ..
129 $ cd ..
130
130
131
131
132 Rebasing B onto H using detach (same as not using it):
132 Rebasing B onto H using detach (same as not using it):
133
133
134 $ hg clone -q -u . a a3
134 $ hg clone -q -u . a a3
135 $ cd a3
135 $ cd a3
136
136
137 $ hg tglog
137 $ hg tglog
138 @ 7: 'H'
138 @ 7: 'H'
139 |
139 |
140 | o 6: 'G'
140 | o 6: 'G'
141 |/|
141 |/|
142 o | 5: 'F'
142 o | 5: 'F'
143 | |
143 | |
144 | o 4: 'E'
144 | o 4: 'E'
145 |/
145 |/
146 | o 3: 'D'
146 | o 3: 'D'
147 | |
147 | |
148 | o 2: 'C'
148 | o 2: 'C'
149 | |
149 | |
150 | o 1: 'B'
150 | o 1: 'B'
151 |/
151 |/
152 o 0: 'A'
152 o 0: 'A'
153
153
154 $ hg rebase --detach -s 1 -d 7
154 $ hg rebase -s 1 -d 7
155 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
155 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
156
156
157 $ hg tglog
157 $ hg tglog
158 @ 7: 'D'
158 @ 7: 'D'
159 |
159 |
160 o 6: 'C'
160 o 6: 'C'
161 |
161 |
162 o 5: 'B'
162 o 5: 'B'
163 |
163 |
164 o 4: 'H'
164 o 4: 'H'
165 |
165 |
166 | o 3: 'G'
166 | o 3: 'G'
167 |/|
167 |/|
168 o | 2: 'F'
168 o | 2: 'F'
169 | |
169 | |
170 | o 1: 'E'
170 | o 1: 'E'
171 |/
171 |/
172 o 0: 'A'
172 o 0: 'A'
173
173
174 $ hg manifest
174 $ hg manifest
175 A
175 A
176 B
176 B
177 C
177 C
178 D
178 D
179 F
179 F
180 H
180 H
181
181
182 $ cd ..
182 $ cd ..
183
183
184
184
185 Rebasing C onto H detaching from B and collapsing:
185 Rebasing C onto H detaching from B and collapsing:
186
186
187 $ hg clone -q -u . a a4
187 $ hg clone -q -u . a a4
188 $ cd a4
188 $ cd a4
189 $ hg phase --force --secret 3
189 $ hg phase --force --secret 3
190
190
191 $ hg tglog
191 $ hg tglog
192 @ 7: 'H'
192 @ 7: 'H'
193 |
193 |
194 | o 6: 'G'
194 | o 6: 'G'
195 |/|
195 |/|
196 o | 5: 'F'
196 o | 5: 'F'
197 | |
197 | |
198 | o 4: 'E'
198 | o 4: 'E'
199 |/
199 |/
200 | o 3: 'D'
200 | o 3: 'D'
201 | |
201 | |
202 | o 2: 'C'
202 | o 2: 'C'
203 | |
203 | |
204 | o 1: 'B'
204 | o 1: 'B'
205 |/
205 |/
206 o 0: 'A'
206 o 0: 'A'
207
207
208 $ hg rebase --detach --collapse -s 2 -d 7
208 $ hg rebase --collapse -s 2 -d 7
209 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
209 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
210
210
211 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
211 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
212 @ 6:secret 'Collapsed revision
212 @ 6:secret 'Collapsed revision
213 | * C
213 | * C
214 | * D'
214 | * D'
215 o 5:draft 'H'
215 o 5:draft 'H'
216 |
216 |
217 | o 4:draft 'G'
217 | o 4:draft 'G'
218 |/|
218 |/|
219 o | 3:draft 'F'
219 o | 3:draft 'F'
220 | |
220 | |
221 | o 2:draft 'E'
221 | o 2:draft 'E'
222 |/
222 |/
223 | o 1:draft 'B'
223 | o 1:draft 'B'
224 |/
224 |/
225 o 0:draft 'A'
225 o 0:draft 'A'
226
226
227 $ hg manifest
227 $ hg manifest
228 A
228 A
229 C
229 C
230 D
230 D
231 F
231 F
232 H
232 H
233
233
234 $ cd ..
234 $ cd ..
235
235
236 Rebasing across null as ancestor
236 Rebasing across null as ancestor
237 $ hg clone -q -U a a5
237 $ hg clone -q -U a a5
238
238
239 $ cd a5
239 $ cd a5
240
240
241 $ echo x > x
241 $ echo x > x
242
242
243 $ hg add x
243 $ hg add x
244
244
245 $ hg ci -m "extra branch"
245 $ hg ci -m "extra branch"
246 created new head
246 created new head
247
247
248 $ hg tglog
248 $ hg tglog
249 @ 8: 'extra branch'
249 @ 8: 'extra branch'
250
250
251 o 7: 'H'
251 o 7: 'H'
252 |
252 |
253 | o 6: 'G'
253 | o 6: 'G'
254 |/|
254 |/|
255 o | 5: 'F'
255 o | 5: 'F'
256 | |
256 | |
257 | o 4: 'E'
257 | o 4: 'E'
258 |/
258 |/
259 | o 3: 'D'
259 | o 3: 'D'
260 | |
260 | |
261 | o 2: 'C'
261 | o 2: 'C'
262 | |
262 | |
263 | o 1: 'B'
263 | o 1: 'B'
264 |/
264 |/
265 o 0: 'A'
265 o 0: 'A'
266
266
267 $ hg rebase --detach -s 1 -d tip
267 $ hg rebase -s 1 -d tip
268 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
268 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
269
269
270 $ hg tglog
270 $ hg tglog
271 @ 8: 'D'
271 @ 8: 'D'
272 |
272 |
273 o 7: 'C'
273 o 7: 'C'
274 |
274 |
275 o 6: 'B'
275 o 6: 'B'
276 |
276 |
277 o 5: 'extra branch'
277 o 5: 'extra branch'
278
278
279 o 4: 'H'
279 o 4: 'H'
280 |
280 |
281 | o 3: 'G'
281 | o 3: 'G'
282 |/|
282 |/|
283 o | 2: 'F'
283 o | 2: 'F'
284 | |
284 | |
285 | o 1: 'E'
285 | o 1: 'E'
286 |/
286 |/
287 o 0: 'A'
287 o 0: 'A'
288
288
289
289
290 $ hg rebase -d 5 -s 7
290 $ hg rebase -d 5 -s 7
291 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg (glob)
291 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/13547172c9c0-backup.hg (glob)
292 $ hg tglog
292 $ hg tglog
293 @ 8: 'D'
293 @ 8: 'D'
294 |
294 |
295 o 7: 'C'
295 o 7: 'C'
296 |
296 |
297 | o 6: 'B'
297 | o 6: 'B'
298 |/
298 |/
299 o 5: 'extra branch'
299 o 5: 'extra branch'
300
300
301 o 4: 'H'
301 o 4: 'H'
302 |
302 |
303 | o 3: 'G'
303 | o 3: 'G'
304 |/|
304 |/|
305 o | 2: 'F'
305 o | 2: 'F'
306 | |
306 | |
307 | o 1: 'E'
307 | o 1: 'E'
308 |/
308 |/
309 o 0: 'A'
309 o 0: 'A'
310
310
311 $ cd ..
311 $ cd ..
312
312
313 Verify that target is not selected as external rev (issue3085)
313 Verify that target is not selected as external rev (issue3085)
314
314
315 $ hg clone -q -U a a6
315 $ hg clone -q -U a a6
316 $ cd a6
316 $ cd a6
317 $ hg up -q 6
317 $ hg up -q 6
318
318
319 $ echo "I" >> E
319 $ echo "I" >> E
320 $ hg ci -m "I"
320 $ hg ci -m "I"
321 $ hg merge 7
321 $ hg merge 7
322 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
322 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
323 (branch merge, don't forget to commit)
323 (branch merge, don't forget to commit)
324 $ hg ci -m "Merge"
324 $ hg ci -m "Merge"
325 $ echo "J" >> F
325 $ echo "J" >> F
326 $ hg ci -m "J"
326 $ hg ci -m "J"
327
327
328 $ hg rebase -s 8 -d 7 --collapse --detach --config ui.merge=internal:other
328 $ hg rebase -s 8 -d 7 --collapse --config ui.merge=internal:other
329 remote changed E which local deleted
329 remote changed E which local deleted
330 use (c)hanged version or leave (d)eleted? c
330 use (c)hanged version or leave (d)eleted? c
331 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
331 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
332
332
333 $ hg tglog
333 $ hg tglog
334 @ 8: 'Collapsed revision
334 @ 8: 'Collapsed revision
335 | * I
335 | * I
336 | * Merge
336 | * Merge
337 | * J'
337 | * J'
338 o 7: 'H'
338 o 7: 'H'
339 |
339 |
340 | o 6: 'G'
340 | o 6: 'G'
341 |/|
341 |/|
342 o | 5: 'F'
342 o | 5: 'F'
343 | |
343 | |
344 | o 4: 'E'
344 | o 4: 'E'
345 |/
345 |/
346 | o 3: 'D'
346 | o 3: 'D'
347 | |
347 | |
348 | o 2: 'C'
348 | o 2: 'C'
349 | |
349 | |
350 | o 1: 'B'
350 | o 1: 'B'
351 |/
351 |/
352 o 0: 'A'
352 o 0: 'A'
353
353
354
354
355 $ hg parents
355 $ hg parents
356 changeset: 8:9472f4b1d736
356 changeset: 8:9472f4b1d736
357 tag: tip
357 tag: tip
358 user: test
358 user: test
359 date: Thu Jan 01 00:00:00 1970 +0000
359 date: Thu Jan 01 00:00:00 1970 +0000
360 summary: Collapsed revision
360 summary: Collapsed revision
361
361
362
362
363 $ cd ..
363 $ cd ..
364
364
365 Ensure --continue restores a correct state (issue3046) and phase:
365 Ensure --continue restores a correct state (issue3046) and phase:
366 $ hg clone -q a a7
366 $ hg clone -q a a7
367 $ cd a7
367 $ cd a7
368 $ hg up -q 3
368 $ hg up -q 3
369 $ echo 'H2' > H
369 $ echo 'H2' > H
370 $ hg ci -A -m 'H2'
370 $ hg ci -A -m 'H2'
371 adding H
371 adding H
372 $ hg phase --force --secret 8
372 $ hg phase --force --secret 8
373 $ hg rebase -s 8 -d 7 --detach --config ui.merge=internal:fail
373 $ hg rebase -s 8 -d 7 --config ui.merge=internal:fail
374 merging H
374 merging H
375 warning: conflicts during merge.
375 warning: conflicts during merge.
376 merging H incomplete! (edit conflicts, then use 'hg resolve --mark')
376 merging H incomplete! (edit conflicts, then use 'hg resolve --mark')
377 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
377 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
378 [255]
378 [255]
379 $ hg resolve --all -t internal:local
379 $ hg resolve --all -t internal:local
380 $ hg rebase -c
380 $ hg rebase -c
381 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg (glob)
381 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6215fafa5447-backup.hg (glob)
382 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
382 $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
383 @ 7:draft 'H'
383 @ 7:draft 'H'
384 |
384 |
385 | o 6:draft 'G'
385 | o 6:draft 'G'
386 |/|
386 |/|
387 o | 5:draft 'F'
387 o | 5:draft 'F'
388 | |
388 | |
389 | o 4:draft 'E'
389 | o 4:draft 'E'
390 |/
390 |/
391 | o 3:draft 'D'
391 | o 3:draft 'D'
392 | |
392 | |
393 | o 2:draft 'C'
393 | o 2:draft 'C'
394 | |
394 | |
395 | o 1:draft 'B'
395 | o 1:draft 'B'
396 |/
396 |/
397 o 0:draft 'A'
397 o 0:draft 'A'
398
398
399
399
400 $ cd ..
400 $ cd ..
@@ -1,430 +1,430 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 >
8 >
9 > [alias]
9 > [alias]
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
11 > EOF
11 > EOF
12
12
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
17 adding changesets
17 adding changesets
18 adding manifests
18 adding manifests
19 adding file changes
19 adding file changes
20 added 8 changesets with 7 changes to 7 files (+2 heads)
20 added 8 changesets with 7 changes to 7 files (+2 heads)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
22 $ hg up tip
22 $ hg up tip
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
24
24
25 $ echo I > I
25 $ echo I > I
26 $ hg ci -AmI
26 $ hg ci -AmI
27 adding I
27 adding I
28
28
29 $ hg tglog
29 $ hg tglog
30 @ 8: 'I'
30 @ 8: 'I'
31 |
31 |
32 o 7: 'H'
32 o 7: 'H'
33 |
33 |
34 | o 6: 'G'
34 | o 6: 'G'
35 |/|
35 |/|
36 o | 5: 'F'
36 o | 5: 'F'
37 | |
37 | |
38 | o 4: 'E'
38 | o 4: 'E'
39 |/
39 |/
40 | o 3: 'D'
40 | o 3: 'D'
41 | |
41 | |
42 | o 2: 'C'
42 | o 2: 'C'
43 | |
43 | |
44 | o 1: 'B'
44 | o 1: 'B'
45 |/
45 |/
46 o 0: 'A'
46 o 0: 'A'
47
47
48 $ cd ..
48 $ cd ..
49
49
50
50
51 These fail:
51 These fail:
52
52
53 $ hg clone -q -u . a a1
53 $ hg clone -q -u . a a1
54 $ cd a1
54 $ cd a1
55
55
56 $ hg rebase -s 8 -d 7
56 $ hg rebase -s 8 -d 7
57 nothing to rebase
57 nothing to rebase
58 [1]
58 [1]
59
59
60 $ hg rebase --continue --abort
60 $ hg rebase --continue --abort
61 abort: cannot use both abort and continue
61 abort: cannot use both abort and continue
62 [255]
62 [255]
63
63
64 $ hg rebase --continue --collapse
64 $ hg rebase --continue --collapse
65 abort: cannot use collapse with continue or abort
65 abort: cannot use collapse with continue or abort
66 [255]
66 [255]
67
67
68 $ hg rebase --continue --dest 4
68 $ hg rebase --continue --dest 4
69 abort: abort and continue do not allow specifying revisions
69 abort: abort and continue do not allow specifying revisions
70 [255]
70 [255]
71
71
72 $ hg rebase --base 5 --source 4
72 $ hg rebase --base 5 --source 4
73 abort: cannot specify both a source and a base
73 abort: cannot specify both a source and a base
74 [255]
74 [255]
75
75
76 $ hg rebase --rev 5 --source 4
76 $ hg rebase --rev 5 --source 4
77 abort: cannot specify both a revision and a source
77 abort: cannot specify both a revision and a source
78 [255]
78 [255]
79 $ hg rebase --base 5 --rev 4
79 $ hg rebase --base 5 --rev 4
80 abort: cannot specify both a revision and a base
80 abort: cannot specify both a revision and a base
81 [255]
81 [255]
82
82
83 $ hg rebase
83 $ hg rebase
84 nothing to rebase
84 nothing to rebase
85 [1]
85 [1]
86
86
87 $ hg up -q 7
87 $ hg up -q 7
88
88
89 $ hg rebase --traceback
89 $ hg rebase --traceback
90 nothing to rebase
90 nothing to rebase
91 [1]
91 [1]
92
92
93
93
94 These work:
94 These work:
95
95
96 Rebase with no arguments (from 3 onto 8):
96 Rebase with no arguments (from 3 onto 8):
97
97
98 $ hg up -q -C 3
98 $ hg up -q -C 3
99
99
100 $ hg rebase
100 $ hg rebase
101 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
101 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
102
102
103 $ hg tglog
103 $ hg tglog
104 @ 8: 'D'
104 @ 8: 'D'
105 |
105 |
106 o 7: 'C'
106 o 7: 'C'
107 |
107 |
108 o 6: 'B'
108 o 6: 'B'
109 |
109 |
110 o 5: 'I'
110 o 5: 'I'
111 |
111 |
112 o 4: 'H'
112 o 4: 'H'
113 |
113 |
114 | o 3: 'G'
114 | o 3: 'G'
115 |/|
115 |/|
116 o | 2: 'F'
116 o | 2: 'F'
117 | |
117 | |
118 | o 1: 'E'
118 | o 1: 'E'
119 |/
119 |/
120 o 0: 'A'
120 o 0: 'A'
121
121
122 Try to rollback after a rebase (fail):
122 Try to rollback after a rebase (fail):
123
123
124 $ hg rollback
124 $ hg rollback
125 no rollback information available
125 no rollback information available
126 [1]
126 [1]
127
127
128 $ cd ..
128 $ cd ..
129
129
130
130
131 Rebase with base == '.' => same as no arguments (from 3 onto 8):
131 Rebase with base == '.' => same as no arguments (from 3 onto 8):
132
132
133 $ hg clone -q -u 3 a a2
133 $ hg clone -q -u 3 a a2
134 $ cd a2
134 $ cd a2
135
135
136 $ hg rebase --base .
136 $ hg rebase --base .
137 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
137 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
138
138
139 $ hg tglog
139 $ hg tglog
140 @ 8: 'D'
140 @ 8: 'D'
141 |
141 |
142 o 7: 'C'
142 o 7: 'C'
143 |
143 |
144 o 6: 'B'
144 o 6: 'B'
145 |
145 |
146 o 5: 'I'
146 o 5: 'I'
147 |
147 |
148 o 4: 'H'
148 o 4: 'H'
149 |
149 |
150 | o 3: 'G'
150 | o 3: 'G'
151 |/|
151 |/|
152 o | 2: 'F'
152 o | 2: 'F'
153 | |
153 | |
154 | o 1: 'E'
154 | o 1: 'E'
155 |/
155 |/
156 o 0: 'A'
156 o 0: 'A'
157
157
158 $ cd ..
158 $ cd ..
159
159
160
160
161 Rebase with dest == branch(.) => same as no arguments (from 3 onto 8):
161 Rebase with dest == branch(.) => same as no arguments (from 3 onto 8):
162
162
163 $ hg clone -q -u 3 a a3
163 $ hg clone -q -u 3 a a3
164 $ cd a3
164 $ cd a3
165
165
166 $ hg rebase --dest 'branch(.)'
166 $ hg rebase --dest 'branch(.)'
167 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
167 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
168
168
169 $ hg tglog
169 $ hg tglog
170 @ 8: 'D'
170 @ 8: 'D'
171 |
171 |
172 o 7: 'C'
172 o 7: 'C'
173 |
173 |
174 o 6: 'B'
174 o 6: 'B'
175 |
175 |
176 o 5: 'I'
176 o 5: 'I'
177 |
177 |
178 o 4: 'H'
178 o 4: 'H'
179 |
179 |
180 | o 3: 'G'
180 | o 3: 'G'
181 |/|
181 |/|
182 o | 2: 'F'
182 o | 2: 'F'
183 | |
183 | |
184 | o 1: 'E'
184 | o 1: 'E'
185 |/
185 |/
186 o 0: 'A'
186 o 0: 'A'
187
187
188 $ cd ..
188 $ cd ..
189
189
190
190
191 Specify only source (from 2 onto 8):
191 Specify only source (from 2 onto 8):
192
192
193 $ hg clone -q -u . a a4
193 $ hg clone -q -u . a a4
194 $ cd a4
194 $ cd a4
195
195
196 $ hg rebase --source 'desc("C")'
196 $ hg rebase --source 'desc("C")'
197 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
197 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
198
198
199 $ hg tglog
199 $ hg tglog
200 @ 8: 'D'
200 @ 8: 'D'
201 |
201 |
202 o 7: 'C'
202 o 7: 'C'
203 |\
203 |
204 | o 6: 'I'
204 o 6: 'I'
205 | |
205 |
206 | o 5: 'H'
206 o 5: 'H'
207 |
208 | o 4: 'G'
209 |/|
210 o | 3: 'F'
207 | |
211 | |
208 | | o 4: 'G'
212 | o 2: 'E'
209 | |/|
213 |/
210 | o | 3: 'F'
214 | o 1: 'B'
211 | | |
212 | | o 2: 'E'
213 | |/
214 o | 1: 'B'
215 |/
215 |/
216 o 0: 'A'
216 o 0: 'A'
217
217
218 $ cd ..
218 $ cd ..
219
219
220
220
221 Specify only dest (from 3 onto 6):
221 Specify only dest (from 3 onto 6):
222
222
223 $ hg clone -q -u 3 a a5
223 $ hg clone -q -u 3 a a5
224 $ cd a5
224 $ cd a5
225
225
226 $ hg rebase --dest 6
226 $ hg rebase --dest 6
227 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
227 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
228
228
229 $ hg tglog
229 $ hg tglog
230 @ 8: 'D'
230 @ 8: 'D'
231 |
231 |
232 o 7: 'C'
232 o 7: 'C'
233 |
233 |
234 o 6: 'B'
234 o 6: 'B'
235 |
235 |
236 | o 5: 'I'
236 | o 5: 'I'
237 | |
237 | |
238 | o 4: 'H'
238 | o 4: 'H'
239 | |
239 | |
240 o | 3: 'G'
240 o | 3: 'G'
241 |\|
241 |\|
242 | o 2: 'F'
242 | o 2: 'F'
243 | |
243 | |
244 o | 1: 'E'
244 o | 1: 'E'
245 |/
245 |/
246 o 0: 'A'
246 o 0: 'A'
247
247
248 $ cd ..
248 $ cd ..
249
249
250
250
251 Specify only base (from 1 onto 8):
251 Specify only base (from 1 onto 8):
252
252
253 $ hg clone -q -u . a a6
253 $ hg clone -q -u . a a6
254 $ cd a6
254 $ cd a6
255
255
256 $ hg rebase --base 'desc("D")'
256 $ hg rebase --base 'desc("D")'
257 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
257 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
258
258
259 $ hg tglog
259 $ hg tglog
260 @ 8: 'D'
260 @ 8: 'D'
261 |
261 |
262 o 7: 'C'
262 o 7: 'C'
263 |
263 |
264 o 6: 'B'
264 o 6: 'B'
265 |
265 |
266 o 5: 'I'
266 o 5: 'I'
267 |
267 |
268 o 4: 'H'
268 o 4: 'H'
269 |
269 |
270 | o 3: 'G'
270 | o 3: 'G'
271 |/|
271 |/|
272 o | 2: 'F'
272 o | 2: 'F'
273 | |
273 | |
274 | o 1: 'E'
274 | o 1: 'E'
275 |/
275 |/
276 o 0: 'A'
276 o 0: 'A'
277
277
278 $ cd ..
278 $ cd ..
279
279
280
280
281 Specify source and dest (from 2 onto 7):
281 Specify source and dest (from 2 onto 7):
282
282
283 $ hg clone -q -u . a a7
283 $ hg clone -q -u . a a7
284 $ cd a7
284 $ cd a7
285
285
286 $ hg rebase --detach --source 2 --dest 7
286 $ hg rebase --source 2 --dest 7
287 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/*-backup.hg (glob)
287 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/*-backup.hg (glob)
288
288
289 $ hg tglog
289 $ hg tglog
290 @ 8: 'D'
290 @ 8: 'D'
291 |
291 |
292 o 7: 'C'
292 o 7: 'C'
293 |
293 |
294 | o 6: 'I'
294 | o 6: 'I'
295 |/
295 |/
296 o 5: 'H'
296 o 5: 'H'
297 |
297 |
298 | o 4: 'G'
298 | o 4: 'G'
299 |/|
299 |/|
300 o | 3: 'F'
300 o | 3: 'F'
301 | |
301 | |
302 | o 2: 'E'
302 | o 2: 'E'
303 |/
303 |/
304 | o 1: 'B'
304 | o 1: 'B'
305 |/
305 |/
306 o 0: 'A'
306 o 0: 'A'
307
307
308 $ cd ..
308 $ cd ..
309
309
310
310
311 Specify base and dest (from 1 onto 7):
311 Specify base and dest (from 1 onto 7):
312
312
313 $ hg clone -q -u . a a8
313 $ hg clone -q -u . a a8
314 $ cd a8
314 $ cd a8
315
315
316 $ hg rebase --base 3 --dest 7
316 $ hg rebase --base 3 --dest 7
317 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/*-backup.hg (glob)
317 saved backup bundle to $TESTTMP/a8/.hg/strip-backup/*-backup.hg (glob)
318
318
319 $ hg tglog
319 $ hg tglog
320 @ 8: 'D'
320 @ 8: 'D'
321 |
321 |
322 o 7: 'C'
322 o 7: 'C'
323 |
323 |
324 o 6: 'B'
324 o 6: 'B'
325 |
325 |
326 | o 5: 'I'
326 | o 5: 'I'
327 |/
327 |/
328 o 4: 'H'
328 o 4: 'H'
329 |
329 |
330 | o 3: 'G'
330 | o 3: 'G'
331 |/|
331 |/|
332 o | 2: 'F'
332 o | 2: 'F'
333 | |
333 | |
334 | o 1: 'E'
334 | o 1: 'E'
335 |/
335 |/
336 o 0: 'A'
336 o 0: 'A'
337
337
338 $ cd ..
338 $ cd ..
339
339
340
340
341 Specify only revs (from 2 onto 8)
341 Specify only revs (from 2 onto 8)
342
342
343 $ hg clone -q -u . a a9
343 $ hg clone -q -u . a a9
344 $ cd a9
344 $ cd a9
345
345
346 $ hg rebase --rev 'desc("C")::'
346 $ hg rebase --rev 'desc("C")::'
347 saved backup bundle to $TESTTMP/a9/.hg/strip-backup/*-backup.hg (glob)
347 saved backup bundle to $TESTTMP/a9/.hg/strip-backup/*-backup.hg (glob)
348
348
349 $ hg tglog
349 $ hg tglog
350 @ 8: 'D'
350 @ 8: 'D'
351 |
351 |
352 o 7: 'C'
352 o 7: 'C'
353 |\
353 |
354 | o 6: 'I'
354 o 6: 'I'
355 | |
355 |
356 | o 5: 'H'
356 o 5: 'H'
357 |
358 | o 4: 'G'
359 |/|
360 o | 3: 'F'
357 | |
361 | |
358 | | o 4: 'G'
362 | o 2: 'E'
359 | |/|
363 |/
360 | o | 3: 'F'
364 | o 1: 'B'
361 | | |
362 | | o 2: 'E'
363 | |/
364 o | 1: 'B'
365 |/
365 |/
366 o 0: 'A'
366 o 0: 'A'
367
367
368 $ cd ..
368 $ cd ..
369
369
370 Test --tool parameter:
370 Test --tool parameter:
371
371
372 $ hg init b
372 $ hg init b
373 $ cd b
373 $ cd b
374
374
375 $ echo c1 > c1
375 $ echo c1 > c1
376 $ hg ci -Am c1
376 $ hg ci -Am c1
377 adding c1
377 adding c1
378
378
379 $ echo c2 > c2
379 $ echo c2 > c2
380 $ hg ci -Am c2
380 $ hg ci -Am c2
381 adding c2
381 adding c2
382
382
383 $ hg up -q 0
383 $ hg up -q 0
384 $ echo c2b > c2
384 $ echo c2b > c2
385 $ hg ci -Am c2b
385 $ hg ci -Am c2b
386 adding c2
386 adding c2
387 created new head
387 created new head
388
388
389 $ cd ..
389 $ cd ..
390
390
391 $ hg clone -q -u . b b1
391 $ hg clone -q -u . b b1
392 $ cd b1
392 $ cd b1
393
393
394 $ hg rebase -s 2 -d 1 --tool internal:local
394 $ hg rebase -s 2 -d 1 --tool internal:local
395 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
395 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
396
396
397 $ hg cat c2
397 $ hg cat c2
398 c2
398 c2
399
399
400 $ cd ..
400 $ cd ..
401
401
402
402
403 $ hg clone -q -u . b b2
403 $ hg clone -q -u . b b2
404 $ cd b2
404 $ cd b2
405
405
406 $ hg rebase -s 2 -d 1 --tool internal:other
406 $ hg rebase -s 2 -d 1 --tool internal:other
407 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/*-backup.hg (glob)
407 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/*-backup.hg (glob)
408
408
409 $ hg cat c2
409 $ hg cat c2
410 c2b
410 c2b
411
411
412 $ cd ..
412 $ cd ..
413
413
414
414
415 $ hg clone -q -u . b b3
415 $ hg clone -q -u . b b3
416 $ cd b3
416 $ cd b3
417
417
418 $ hg rebase -s 2 -d 1 --tool internal:fail
418 $ hg rebase -s 2 -d 1 --tool internal:fail
419 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
419 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
420 [255]
420 [255]
421
421
422 $ hg resolve -l
422 $ hg resolve -l
423 U c2
423 U c2
424
424
425 $ hg resolve -m c2
425 $ hg resolve -m c2
426 $ hg rebase -c --tool internal:fail
426 $ hg rebase -c --tool internal:fail
427 tool option will be ignored
427 tool option will be ignored
428 saved backup bundle to $TESTTMP/b3/.hg/strip-backup/*-backup.hg (glob)
428 saved backup bundle to $TESTTMP/b3/.hg/strip-backup/*-backup.hg (glob)
429
429
430 $ cd ..
430 $ cd ..
@@ -1,547 +1,547 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 >
8 >
9 > [alias]
9 > [alias]
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
10 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
11 > EOF
11 > EOF
12
12
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
16 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
17 adding changesets
17 adding changesets
18 adding manifests
18 adding manifests
19 adding file changes
19 adding file changes
20 added 8 changesets with 7 changes to 7 files (+2 heads)
20 added 8 changesets with 7 changes to 7 files (+2 heads)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
21 (run 'hg heads' to see heads, 'hg merge' to merge)
22 $ hg up tip
22 $ hg up tip
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 $ cd ..
24 $ cd ..
25
25
26
26
27 Rebasing
27 Rebasing
28 D onto H - simple rebase:
28 D onto H - simple rebase:
29
29
30 $ hg clone -q -u . a a1
30 $ hg clone -q -u . a a1
31 $ cd a1
31 $ cd a1
32
32
33 $ hg tglog
33 $ hg tglog
34 @ 7: 'H'
34 @ 7: 'H'
35 |
35 |
36 | o 6: 'G'
36 | o 6: 'G'
37 |/|
37 |/|
38 o | 5: 'F'
38 o | 5: 'F'
39 | |
39 | |
40 | o 4: 'E'
40 | o 4: 'E'
41 |/
41 |/
42 | o 3: 'D'
42 | o 3: 'D'
43 | |
43 | |
44 | o 2: 'C'
44 | o 2: 'C'
45 | |
45 | |
46 | o 1: 'B'
46 | o 1: 'B'
47 |/
47 |/
48 o 0: 'A'
48 o 0: 'A'
49
49
50
50
51 $ hg rebase -s 3 -d 7
51 $ hg rebase -s 3 -d 7
52 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
52 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
53
53
54 $ hg tglog
54 $ hg tglog
55 @ 7: 'D'
55 @ 7: 'D'
56 |\
56 |
57 | o 6: 'H'
57 o 6: 'H'
58 |
59 | o 5: 'G'
60 |/|
61 o | 4: 'F'
58 | |
62 | |
59 | | o 5: 'G'
63 | o 3: 'E'
60 | |/|
64 |/
61 | o | 4: 'F'
65 | o 2: 'C'
62 | | |
63 | | o 3: 'E'
64 | |/
65 o | 2: 'C'
66 | |
66 | |
67 o | 1: 'B'
67 | o 1: 'B'
68 |/
68 |/
69 o 0: 'A'
69 o 0: 'A'
70
70
71 $ cd ..
71 $ cd ..
72
72
73
73
74 D onto F - intermediate point:
74 D onto F - intermediate point:
75
75
76 $ hg clone -q -u . a a2
76 $ hg clone -q -u . a a2
77 $ cd a2
77 $ cd a2
78
78
79 $ hg rebase -s 3 -d 5
79 $ hg rebase -s 3 -d 5
80 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
80 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
81
81
82 $ hg tglog
82 $ hg tglog
83 @ 7: 'D'
83 @ 7: 'D'
84 |\
84 |
85 | | o 6: 'H'
85 | o 6: 'H'
86 | |/
86 |/
87 | | o 5: 'G'
87 | o 5: 'G'
88 | |/|
88 |/|
89 | o | 4: 'F'
89 o | 4: 'F'
90 | | |
91 | | o 3: 'E'
92 | |/
93 o | 2: 'C'
94 | |
90 | |
95 o | 1: 'B'
91 | o 3: 'E'
92 |/
93 | o 2: 'C'
94 | |
95 | o 1: 'B'
96 |/
96 |/
97 o 0: 'A'
97 o 0: 'A'
98
98
99 $ cd ..
99 $ cd ..
100
100
101
101
102 E onto H - skip of G:
102 E onto H - skip of G:
103
103
104 $ hg clone -q -u . a a3
104 $ hg clone -q -u . a a3
105 $ cd a3
105 $ cd a3
106
106
107 $ hg rebase -s 4 -d 7
107 $ hg rebase -s 4 -d 7
108 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
108 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
109
109
110 $ hg tglog
110 $ hg tglog
111 @ 6: 'E'
111 @ 6: 'E'
112 |
112 |
113 o 5: 'H'
113 o 5: 'H'
114 |
114 |
115 o 4: 'F'
115 o 4: 'F'
116 |
116 |
117 | o 3: 'D'
117 | o 3: 'D'
118 | |
118 | |
119 | o 2: 'C'
119 | o 2: 'C'
120 | |
120 | |
121 | o 1: 'B'
121 | o 1: 'B'
122 |/
122 |/
123 o 0: 'A'
123 o 0: 'A'
124
124
125 $ cd ..
125 $ cd ..
126
126
127
127
128 F onto E - rebase of a branching point (skip G):
128 F onto E - rebase of a branching point (skip G):
129
129
130 $ hg clone -q -u . a a4
130 $ hg clone -q -u . a a4
131 $ cd a4
131 $ cd a4
132
132
133 $ hg rebase -s 5 -d 4
133 $ hg rebase -s 5 -d 4
134 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
134 saved backup bundle to $TESTTMP/a4/.hg/strip-backup/*-backup.hg (glob)
135
135
136 $ hg tglog
136 $ hg tglog
137 @ 6: 'H'
137 @ 6: 'H'
138 |
138 |
139 o 5: 'F'
139 o 5: 'F'
140 |
140 |
141 o 4: 'E'
141 o 4: 'E'
142 |
142 |
143 | o 3: 'D'
143 | o 3: 'D'
144 | |
144 | |
145 | o 2: 'C'
145 | o 2: 'C'
146 | |
146 | |
147 | o 1: 'B'
147 | o 1: 'B'
148 |/
148 |/
149 o 0: 'A'
149 o 0: 'A'
150
150
151 $ cd ..
151 $ cd ..
152
152
153
153
154 G onto H - merged revision having a parent in ancestors of target:
154 G onto H - merged revision having a parent in ancestors of target:
155
155
156 $ hg clone -q -u . a a5
156 $ hg clone -q -u . a a5
157 $ cd a5
157 $ cd a5
158
158
159 $ hg rebase -s 6 -d 7
159 $ hg rebase -s 6 -d 7
160 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
160 saved backup bundle to $TESTTMP/a5/.hg/strip-backup/*-backup.hg (glob)
161
161
162 $ hg tglog
162 $ hg tglog
163 @ 7: 'G'
163 @ 7: 'G'
164 |\
164 |\
165 | o 6: 'H'
165 | o 6: 'H'
166 | |
166 | |
167 | o 5: 'F'
167 | o 5: 'F'
168 | |
168 | |
169 o | 4: 'E'
169 o | 4: 'E'
170 |/
170 |/
171 | o 3: 'D'
171 | o 3: 'D'
172 | |
172 | |
173 | o 2: 'C'
173 | o 2: 'C'
174 | |
174 | |
175 | o 1: 'B'
175 | o 1: 'B'
176 |/
176 |/
177 o 0: 'A'
177 o 0: 'A'
178
178
179 $ cd ..
179 $ cd ..
180
180
181
181
182 F onto B - G maintains E as parent:
182 F onto B - G maintains E as parent:
183
183
184 $ hg clone -q -u . a a6
184 $ hg clone -q -u . a a6
185 $ cd a6
185 $ cd a6
186
186
187 $ hg rebase -s 5 -d 1
187 $ hg rebase -s 5 -d 1
188 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
188 saved backup bundle to $TESTTMP/a6/.hg/strip-backup/*-backup.hg (glob)
189
189
190 $ hg tglog
190 $ hg tglog
191 @ 7: 'H'
191 @ 7: 'H'
192 |
192 |
193 | o 6: 'G'
193 | o 6: 'G'
194 |/|
194 |/|
195 o | 5: 'F'
195 o | 5: 'F'
196 | |
196 | |
197 | o 4: 'E'
197 | o 4: 'E'
198 | |
198 | |
199 | | o 3: 'D'
199 | | o 3: 'D'
200 | | |
200 | | |
201 +---o 2: 'C'
201 +---o 2: 'C'
202 | |
202 | |
203 o | 1: 'B'
203 o | 1: 'B'
204 |/
204 |/
205 o 0: 'A'
205 o 0: 'A'
206
206
207 $ cd ..
207 $ cd ..
208
208
209
209
210 These will fail (using --source):
210 These will fail (using --source):
211
211
212 G onto F - rebase onto an ancestor:
212 G onto F - rebase onto an ancestor:
213
213
214 $ hg clone -q -u . a a7
214 $ hg clone -q -u . a a7
215 $ cd a7
215 $ cd a7
216
216
217 $ hg rebase -s 6 -d 5
217 $ hg rebase -s 6 -d 5
218 nothing to rebase
218 nothing to rebase
219 [1]
219 [1]
220
220
221 F onto G - rebase onto a descendant:
221 F onto G - rebase onto a descendant:
222
222
223 $ hg rebase -s 5 -d 6
223 $ hg rebase -s 5 -d 6
224 abort: source is ancestor of destination
224 abort: source is ancestor of destination
225 [255]
225 [255]
226
226
227 G onto B - merge revision with both parents not in ancestors of target:
227 G onto B - merge revision with both parents not in ancestors of target:
228
228
229 $ hg rebase -s 6 -d 1
229 $ hg rebase -s 6 -d 1
230 abort: cannot use revision 6 as base, result would have 3 parents
230 abort: cannot use revision 6 as base, result would have 3 parents
231 [255]
231 [255]
232
232
233
233
234 These will abort gracefully (using --base):
234 These will abort gracefully (using --base):
235
235
236 G onto G - rebase onto same changeset:
236 G onto G - rebase onto same changeset:
237
237
238 $ hg rebase -b 6 -d 6
238 $ hg rebase -b 6 -d 6
239 nothing to rebase
239 nothing to rebase
240 [1]
240 [1]
241
241
242 G onto F - rebase onto an ancestor:
242 G onto F - rebase onto an ancestor:
243
243
244 $ hg rebase -b 6 -d 5
244 $ hg rebase -b 6 -d 5
245 nothing to rebase
245 nothing to rebase
246 [1]
246 [1]
247
247
248 F onto G - rebase onto a descendant:
248 F onto G - rebase onto a descendant:
249
249
250 $ hg rebase -b 5 -d 6
250 $ hg rebase -b 5 -d 6
251 nothing to rebase
251 nothing to rebase
252 [1]
252 [1]
253
253
254 C onto A - rebase onto an ancestor:
254 C onto A - rebase onto an ancestor:
255
255
256 $ hg rebase -d 0 -s 2
256 $ hg rebase -d 0 -s 2
257 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg (glob)
257 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/5fddd98957c8-backup.hg (glob)
258 $ hg tglog
258 $ hg tglog
259 @ 7: 'D'
259 @ 7: 'D'
260 |
260 |
261 o 6: 'C'
261 o 6: 'C'
262 |
262 |
263 | o 5: 'H'
263 | o 5: 'H'
264 | |
264 | |
265 | | o 4: 'G'
265 | | o 4: 'G'
266 | |/|
266 | |/|
267 | o | 3: 'F'
267 | o | 3: 'F'
268 |/ /
268 |/ /
269 | o 2: 'E'
269 | o 2: 'E'
270 |/
270 |/
271 | o 1: 'B'
271 | o 1: 'B'
272 |/
272 |/
273 o 0: 'A'
273 o 0: 'A'
274
274
275
275
276 Check rebasing public changeset
276 Check rebasing public changeset
277
277
278 $ hg pull --config phases.publish=True -q -r 6 . # update phase of 6
278 $ hg pull --config phases.publish=True -q -r 6 . # update phase of 6
279 $ hg rebase -d 5 -b 6
279 $ hg rebase -d 5 -b 6
280 abort: can't rebase immutable changeset e1c4361dd923
280 abort: can't rebase immutable changeset e1c4361dd923
281 (see hg help phases for details)
281 (see hg help phases for details)
282 [255]
282 [255]
283
283
284 $ hg rebase -d 5 -b 6 --keep
284 $ hg rebase -d 5 -b 6 --keep
285
285
286 Check rebasing mutable changeset
286 Check rebasing mutable changeset
287 Source phase greater or equal to destination phase: new changeset get the phase of source:
287 Source phase greater or equal to destination phase: new changeset get the phase of source:
288 $ hg rebase -s9 -d0
288 $ hg rebase -s9 -d0
289 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-backup.hg (glob)
289 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-backup.hg (glob)
290 $ hg log --template "{phase}\n" -r 9
290 $ hg log --template "{phase}\n" -r 9
291 draft
291 draft
292 $ hg rebase -s9 -d1
292 $ hg rebase -s9 -d1
293 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-backup.hg (glob)
293 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-backup.hg (glob)
294 $ hg log --template "{phase}\n" -r 9
294 $ hg log --template "{phase}\n" -r 9
295 draft
295 draft
296 $ hg phase --force --secret 9
296 $ hg phase --force --secret 9
297 $ hg rebase -s9 -d0
297 $ hg rebase -s9 -d0
298 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-backup.hg (glob)
298 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-backup.hg (glob)
299 $ hg log --template "{phase}\n" -r 9
299 $ hg log --template "{phase}\n" -r 9
300 secret
300 secret
301 $ hg rebase -s9 -d1
301 $ hg rebase -s9 -d1
302 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-backup.hg (glob)
302 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-backup.hg (glob)
303 $ hg log --template "{phase}\n" -r 9
303 $ hg log --template "{phase}\n" -r 9
304 secret
304 secret
305 Source phase lower than destination phase: new changeset get the phase of destination:
305 Source phase lower than destination phase: new changeset get the phase of destination:
306 $ hg rebase -s7 -d9
306 $ hg rebase -s8 -d9
307 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c9659aac0000-backup.hg (glob)
307 saved backup bundle to $TESTTMP/a7/.hg/strip-backup/6d4f22462821-backup.hg
308 $ hg log --template "{phase}\n" -r 9
308 $ hg log --template "{phase}\n" -r 'rev(9)'
309 secret
309 secret
310
310
311 $ cd ..
311 $ cd ..
312
312
313 Test for revset
313 Test for revset
314
314
315 We need a bit different graph
315 We need a bit different graph
316 All destination are B
316 All destination are B
317
317
318 $ hg init ah
318 $ hg init ah
319 $ cd ah
319 $ cd ah
320 $ hg unbundle "$TESTDIR/bundles/rebase-revset.hg"
320 $ hg unbundle "$TESTDIR/bundles/rebase-revset.hg"
321 adding changesets
321 adding changesets
322 adding manifests
322 adding manifests
323 adding file changes
323 adding file changes
324 added 9 changesets with 9 changes to 9 files (+2 heads)
324 added 9 changesets with 9 changes to 9 files (+2 heads)
325 (run 'hg heads' to see heads, 'hg merge' to merge)
325 (run 'hg heads' to see heads, 'hg merge' to merge)
326 $ hg tglog
326 $ hg tglog
327 o 8: 'I'
327 o 8: 'I'
328 |
328 |
329 o 7: 'H'
329 o 7: 'H'
330 |
330 |
331 o 6: 'G'
331 o 6: 'G'
332 |
332 |
333 | o 5: 'F'
333 | o 5: 'F'
334 | |
334 | |
335 | o 4: 'E'
335 | o 4: 'E'
336 |/
336 |/
337 o 3: 'D'
337 o 3: 'D'
338 |
338 |
339 o 2: 'C'
339 o 2: 'C'
340 |
340 |
341 | o 1: 'B'
341 | o 1: 'B'
342 |/
342 |/
343 o 0: 'A'
343 o 0: 'A'
344
344
345 $ cd ..
345 $ cd ..
346
346
347
347
348 Simple case with keep:
348 Simple case with keep:
349
349
350 Source on have two descendant heads but ask for one
350 Source on have two descendant heads but ask for one
351
351
352 $ hg clone -q -u . ah ah1
352 $ hg clone -q -u . ah ah1
353 $ cd ah1
353 $ cd ah1
354 $ hg rebase -r '2::8' -d 1
354 $ hg rebase -r '2::8' -d 1
355 abort: can't remove original changesets with unrebased descendants
355 abort: can't remove original changesets with unrebased descendants
356 (use --keep to keep original changesets)
356 (use --keep to keep original changesets)
357 [255]
357 [255]
358 $ hg rebase -r '2::8' -d 1 --keep
358 $ hg rebase -r '2::8' -d 1 --keep
359 $ hg tglog
359 $ hg tglog
360 @ 13: 'I'
360 @ 13: 'I'
361 |
361 |
362 o 12: 'H'
362 o 12: 'H'
363 |
363 |
364 o 11: 'G'
364 o 11: 'G'
365 |
365 |
366 o 10: 'D'
366 o 10: 'D'
367 |
367 |
368 o 9: 'C'
368 o 9: 'C'
369 |
369 |
370 | o 8: 'I'
370 | o 8: 'I'
371 | |
371 | |
372 | o 7: 'H'
372 | o 7: 'H'
373 | |
373 | |
374 | o 6: 'G'
374 | o 6: 'G'
375 | |
375 | |
376 | | o 5: 'F'
376 | | o 5: 'F'
377 | | |
377 | | |
378 | | o 4: 'E'
378 | | o 4: 'E'
379 | |/
379 | |/
380 | o 3: 'D'
380 | o 3: 'D'
381 | |
381 | |
382 | o 2: 'C'
382 | o 2: 'C'
383 | |
383 | |
384 o | 1: 'B'
384 o | 1: 'B'
385 |/
385 |/
386 o 0: 'A'
386 o 0: 'A'
387
387
388
388
389 $ cd ..
389 $ cd ..
390
390
391 Base on have one descendant heads we ask for but common ancestor have two
391 Base on have one descendant heads we ask for but common ancestor have two
392
392
393 $ hg clone -q -u . ah ah2
393 $ hg clone -q -u . ah ah2
394 $ cd ah2
394 $ cd ah2
395 $ hg rebase -r '3::8' -d 1
395 $ hg rebase -r '3::8' -d 1
396 abort: can't remove original changesets with unrebased descendants
396 abort: can't remove original changesets with unrebased descendants
397 (use --keep to keep original changesets)
397 (use --keep to keep original changesets)
398 [255]
398 [255]
399 $ hg rebase -r '3::8' -d 1 --keep
399 $ hg rebase -r '3::8' -d 1 --keep
400 $ hg tglog
400 $ hg tglog
401 @ 12: 'I'
401 @ 12: 'I'
402 |
402 |
403 o 11: 'H'
403 o 11: 'H'
404 |
404 |
405 o 10: 'G'
405 o 10: 'G'
406 |
406 |
407 o 9: 'D'
407 o 9: 'D'
408 |\
408 |
409 | | o 8: 'I'
409 | o 8: 'I'
410 | | |
410 | |
411 | | o 7: 'H'
411 | o 7: 'H'
412 | |
413 | o 6: 'G'
414 | |
415 | | o 5: 'F'
412 | | |
416 | | |
413 | | o 6: 'G'
417 | | o 4: 'E'
414 | | |
415 | | | o 5: 'F'
416 | | | |
417 | | | o 4: 'E'
418 | | |/
419 | | o 3: 'D'
420 | |/
418 | |/
419 | o 3: 'D'
420 | |
421 | o 2: 'C'
421 | o 2: 'C'
422 | |
422 | |
423 o | 1: 'B'
423 o | 1: 'B'
424 |/
424 |/
425 o 0: 'A'
425 o 0: 'A'
426
426
427
427
428 $ cd ..
428 $ cd ..
429
429
430 rebase subset
430 rebase subset
431
431
432 $ hg clone -q -u . ah ah3
432 $ hg clone -q -u . ah ah3
433 $ cd ah3
433 $ cd ah3
434 $ hg rebase -r '3::7' -d 1
434 $ hg rebase -r '3::7' -d 1
435 abort: can't remove original changesets with unrebased descendants
435 abort: can't remove original changesets with unrebased descendants
436 (use --keep to keep original changesets)
436 (use --keep to keep original changesets)
437 [255]
437 [255]
438 $ hg rebase -r '3::7' -d 1 --keep
438 $ hg rebase -r '3::7' -d 1 --keep
439 $ hg tglog
439 $ hg tglog
440 @ 11: 'H'
440 @ 11: 'H'
441 |
441 |
442 o 10: 'G'
442 o 10: 'G'
443 |
443 |
444 o 9: 'D'
444 o 9: 'D'
445 |\
445 |
446 | | o 8: 'I'
446 | o 8: 'I'
447 | | |
447 | |
448 | | o 7: 'H'
448 | o 7: 'H'
449 | |
450 | o 6: 'G'
451 | |
452 | | o 5: 'F'
449 | | |
453 | | |
450 | | o 6: 'G'
454 | | o 4: 'E'
451 | | |
452 | | | o 5: 'F'
453 | | | |
454 | | | o 4: 'E'
455 | | |/
456 | | o 3: 'D'
457 | |/
455 | |/
456 | o 3: 'D'
457 | |
458 | o 2: 'C'
458 | o 2: 'C'
459 | |
459 | |
460 o | 1: 'B'
460 o | 1: 'B'
461 |/
461 |/
462 o 0: 'A'
462 o 0: 'A'
463
463
464
464
465 $ cd ..
465 $ cd ..
466
466
467 rebase subset with multiple head
467 rebase subset with multiple head
468
468
469 $ hg clone -q -u . ah ah4
469 $ hg clone -q -u . ah ah4
470 $ cd ah4
470 $ cd ah4
471 $ hg rebase -r '3::(7+5)' -d 1
471 $ hg rebase -r '3::(7+5)' -d 1
472 abort: can't remove original changesets with unrebased descendants
472 abort: can't remove original changesets with unrebased descendants
473 (use --keep to keep original changesets)
473 (use --keep to keep original changesets)
474 [255]
474 [255]
475 $ hg rebase -r '3::(7+5)' -d 1 --keep
475 $ hg rebase -r '3::(7+5)' -d 1 --keep
476 $ hg tglog
476 $ hg tglog
477 @ 13: 'H'
477 @ 13: 'H'
478 |
478 |
479 o 12: 'G'
479 o 12: 'G'
480 |
480 |
481 | o 11: 'F'
481 | o 11: 'F'
482 | |
482 | |
483 | o 10: 'E'
483 | o 10: 'E'
484 |/
484 |/
485 o 9: 'D'
485 o 9: 'D'
486 |\
486 |
487 | | o 8: 'I'
487 | o 8: 'I'
488 | | |
488 | |
489 | | o 7: 'H'
489 | o 7: 'H'
490 | |
491 | o 6: 'G'
492 | |
493 | | o 5: 'F'
490 | | |
494 | | |
491 | | o 6: 'G'
495 | | o 4: 'E'
492 | | |
493 | | | o 5: 'F'
494 | | | |
495 | | | o 4: 'E'
496 | | |/
497 | | o 3: 'D'
498 | |/
496 | |/
497 | o 3: 'D'
498 | |
499 | o 2: 'C'
499 | o 2: 'C'
500 | |
500 | |
501 o | 1: 'B'
501 o | 1: 'B'
502 |/
502 |/
503 o 0: 'A'
503 o 0: 'A'
504
504
505
505
506 $ cd ..
506 $ cd ..
507
507
508 More advanced tests
508 More advanced tests
509
509
510 rebase on ancestor with revset
510 rebase on ancestor with revset
511
511
512 $ hg clone -q -u . ah ah5
512 $ hg clone -q -u . ah ah5
513 $ cd ah5
513 $ cd ah5
514 $ hg rebase -r '6::' -d 2
514 $ hg rebase -r '6::' -d 2
515 saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg (glob)
515 saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg (glob)
516 $ hg tglog
516 $ hg tglog
517 @ 8: 'I'
517 @ 8: 'I'
518 |
518 |
519 o 7: 'H'
519 o 7: 'H'
520 |
520 |
521 o 6: 'G'
521 o 6: 'G'
522 |
522 |
523 | o 5: 'F'
523 | o 5: 'F'
524 | |
524 | |
525 | o 4: 'E'
525 | o 4: 'E'
526 | |
526 | |
527 | o 3: 'D'
527 | o 3: 'D'
528 |/
528 |/
529 o 2: 'C'
529 o 2: 'C'
530 |
530 |
531 | o 1: 'B'
531 | o 1: 'B'
532 |/
532 |/
533 o 0: 'A'
533 o 0: 'A'
534
534
535 $ cd ..
535 $ cd ..
536
536
537
537
538 rebase with multiple root.
538 rebase with multiple root.
539 We rebase E and G on B
539 We rebase E and G on B
540 We would expect heads are I, F if it was supported
540 We would expect heads are I, F if it was supported
541
541
542 $ hg clone -q -u . ah ah6
542 $ hg clone -q -u . ah ah6
543 $ cd ah6
543 $ cd ah6
544 $ hg rebase -r '(4+6)::' -d 1
544 $ hg rebase -r '(4+6)::' -d 1
545 abort: can't rebase multiple roots
545 abort: can't rebase multiple roots
546 [255]
546 [255]
547 $ cd ..
547 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now