##// END OF EJS Templates
Fix up rebase's handling of strip backups
Matt Mackall -
r11201:34023f2c default
parent child Browse files
Show More
@@ -1,556 +1,558 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, error
17 from mercurial import hg, util, repair, merge, cmdutil, commands, error
18 from mercurial import extensions, ancestor, copies, patch
18 from mercurial import extensions, ancestor, copies, patch
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 def rebase(ui, repo, **opts):
27 def rebase(ui, repo, **opts):
28 """move changeset (and descendants) to a different branch
28 """move changeset (and descendants) to a different branch
29
29
30 Rebase uses repeated merging to graft changesets from one part of
30 Rebase uses repeated merging to graft changesets from one part of
31 history (the source) onto another (the destination). This can be
31 history (the source) onto another (the destination). This can be
32 useful for linearizing *local* changes relative to a master
32 useful for linearizing *local* changes relative to a master
33 development tree.
33 development tree.
34
34
35 You should not rebase changesets that have already been shared
35 You should not rebase changesets that have already been shared
36 with others. Doing so will force everybody else to perform the
36 with others. Doing so will force everybody else to perform the
37 same rebase or they will end up with duplicated changesets after
37 same rebase or they will end up with duplicated changesets after
38 pulling in your rebased changesets.
38 pulling in your rebased changesets.
39
39
40 If you don't specify a destination changeset (``-d/--dest``),
40 If you don't specify a destination changeset (``-d/--dest``),
41 rebase uses the tipmost head of the current named branch as the
41 rebase uses the tipmost head of the current named branch as the
42 destination. (The destination changeset is not modified by
42 destination. (The destination changeset is not modified by
43 rebasing, but new changesets are added as its descendants.)
43 rebasing, but new changesets are added as its descendants.)
44
44
45 You can specify which changesets to rebase in two ways: as a
45 You can specify which changesets to rebase in two ways: as a
46 "source" changeset or as a "base" changeset. Both are shorthand
46 "source" changeset or as a "base" changeset. Both are shorthand
47 for a topologically related set of changesets (the "source
47 for a topologically related set of changesets (the "source
48 branch"). If you specify source (``-s/--source``), rebase will
48 branch"). If you specify source (``-s/--source``), rebase will
49 rebase that changeset and all of its descendants onto dest. If you
49 rebase that changeset and all of its descendants onto dest. If you
50 specify base (``-b/--base``), rebase will select ancestors of base
50 specify base (``-b/--base``), rebase will select ancestors of base
51 back to but not including the common ancestor with dest. Thus,
51 back to but not including the common ancestor with dest. Thus,
52 ``-b`` is less precise but more convenient than ``-s``: you can
52 ``-b`` is less precise but more convenient than ``-s``: you can
53 specify any changeset in the source branch, and rebase will select
53 specify any changeset in the source branch, and rebase will select
54 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
54 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
55 uses the parent of the working directory as the base.
55 uses the parent of the working directory as the base.
56
56
57 By default, rebase recreates the changesets in the source branch
57 By default, rebase recreates the changesets in the source branch
58 as descendants of dest and then destroys the originals. Use
58 as descendants of dest and then destroys the originals. Use
59 ``--keep`` to preserve the original source changesets. Some
59 ``--keep`` to preserve the original source changesets. Some
60 changesets in the source branch (e.g. merges from the destination
60 changesets in the source branch (e.g. merges from the destination
61 branch) may be dropped if they no longer contribute any change.
61 branch) may be dropped if they no longer contribute any change.
62
62
63 One result of the rules for selecting the destination changeset
63 One result of the rules for selecting the destination changeset
64 and source branch is that, unlike ``merge``, rebase will do
64 and source branch is that, unlike ``merge``, rebase will do
65 nothing if you are at the latest (tipmost) head of a named branch
65 nothing if you are at the latest (tipmost) head of a named branch
66 with two heads. You need to explicitly specify source and/or
66 with two heads. You need to explicitly specify source and/or
67 destination (or ``update`` to the other head, if it's the head of
67 destination (or ``update`` to the other head, if it's the head of
68 the intended source branch).
68 the intended source branch).
69
69
70 If a rebase is interrupted to manually resolve a merge, it can be
70 If a rebase is interrupted to manually resolve a merge, it can be
71 continued with --continue/-c or aborted with --abort/-a.
71 continued with --continue/-c or aborted with --abort/-a.
72 """
72 """
73 originalwd = target = None
73 originalwd = target = None
74 external = nullrev
74 external = nullrev
75 state = {}
75 state = {}
76 skipped = set()
76 skipped = set()
77 targetancestors = set()
77 targetancestors = set()
78
78
79 lock = wlock = None
79 lock = wlock = None
80 try:
80 try:
81 lock = repo.lock()
81 lock = repo.lock()
82 wlock = repo.wlock()
82 wlock = repo.wlock()
83
83
84 # Validate input and define rebasing points
84 # Validate input and define rebasing points
85 destf = opts.get('dest', None)
85 destf = opts.get('dest', None)
86 srcf = opts.get('source', None)
86 srcf = opts.get('source', None)
87 basef = opts.get('base', None)
87 basef = opts.get('base', None)
88 contf = opts.get('continue')
88 contf = opts.get('continue')
89 abortf = opts.get('abort')
89 abortf = opts.get('abort')
90 collapsef = opts.get('collapse', False)
90 collapsef = opts.get('collapse', False)
91 extrafn = opts.get('extrafn')
91 extrafn = opts.get('extrafn')
92 keepf = opts.get('keep', False)
92 keepf = opts.get('keep', False)
93 keepbranchesf = opts.get('keepbranches', False)
93 keepbranchesf = opts.get('keepbranches', False)
94 detachf = opts.get('detach', False)
94 detachf = opts.get('detach', False)
95 # keepopen is not meant for use on the command line, but by
95 # keepopen is not meant for use on the command line, but by
96 # other extensions
96 # other extensions
97 keepopen = opts.get('keepopen', False)
97 keepopen = opts.get('keepopen', False)
98
98
99 if contf or abortf:
99 if contf or abortf:
100 if contf and abortf:
100 if contf and abortf:
101 raise error.ParseError('rebase',
101 raise error.ParseError('rebase',
102 _('cannot use both abort and continue'))
102 _('cannot use both abort and continue'))
103 if collapsef:
103 if collapsef:
104 raise error.ParseError(
104 raise error.ParseError(
105 'rebase', _('cannot use collapse with continue or abort'))
105 'rebase', _('cannot use collapse with continue or abort'))
106
106
107 if detachf:
107 if detachf:
108 raise error.ParseError(
108 raise error.ParseError(
109 'rebase', _('cannot use detach with continue or abort'))
109 'rebase', _('cannot use detach with continue or abort'))
110
110
111 if srcf or basef or destf:
111 if srcf or basef or destf:
112 raise error.ParseError('rebase',
112 raise error.ParseError('rebase',
113 _('abort and continue do not allow specifying revisions'))
113 _('abort and continue do not allow specifying revisions'))
114
114
115 (originalwd, target, state, collapsef, keepf,
115 (originalwd, target, state, collapsef, keepf,
116 keepbranchesf, external) = restorestatus(repo)
116 keepbranchesf, external) = restorestatus(repo)
117 if abortf:
117 if abortf:
118 abort(repo, originalwd, target, state)
118 abort(repo, originalwd, target, state)
119 return
119 return
120 else:
120 else:
121 if srcf and basef:
121 if srcf and basef:
122 raise error.ParseError('rebase', _('cannot specify both a '
122 raise error.ParseError('rebase', _('cannot specify both a '
123 'revision and a base'))
123 'revision and a base'))
124 if detachf:
124 if detachf:
125 if not srcf:
125 if not srcf:
126 raise error.ParseError(
126 raise error.ParseError(
127 'rebase', _('detach requires a revision to be specified'))
127 'rebase', _('detach requires a revision to be specified'))
128 if basef:
128 if basef:
129 raise error.ParseError(
129 raise error.ParseError(
130 'rebase', _('cannot specify a base with detach'))
130 'rebase', _('cannot specify a base with detach'))
131
131
132 cmdutil.bail_if_changed(repo)
132 cmdutil.bail_if_changed(repo)
133 result = buildstate(repo, destf, srcf, basef, detachf)
133 result = buildstate(repo, destf, srcf, basef, detachf)
134 if not result:
134 if not result:
135 # Empty state built, nothing to rebase
135 # Empty state built, nothing to rebase
136 ui.status(_('nothing to rebase\n'))
136 ui.status(_('nothing to rebase\n'))
137 return
137 return
138 else:
138 else:
139 originalwd, target, state = result
139 originalwd, target, state = result
140 if collapsef:
140 if collapsef:
141 targetancestors = set(repo.changelog.ancestors(target))
141 targetancestors = set(repo.changelog.ancestors(target))
142 external = checkexternal(repo, state, targetancestors)
142 external = checkexternal(repo, state, targetancestors)
143
143
144 if keepbranchesf:
144 if keepbranchesf:
145 if extrafn:
145 if extrafn:
146 raise error.ParseError(
146 raise error.ParseError(
147 'rebase', _('cannot use both keepbranches and extrafn'))
147 'rebase', _('cannot use both keepbranches and extrafn'))
148 def extrafn(ctx, extra):
148 def extrafn(ctx, extra):
149 extra['branch'] = ctx.branch()
149 extra['branch'] = ctx.branch()
150
150
151 # Rebase
151 # Rebase
152 if not targetancestors:
152 if not targetancestors:
153 targetancestors = set(repo.changelog.ancestors(target))
153 targetancestors = set(repo.changelog.ancestors(target))
154 targetancestors.add(target)
154 targetancestors.add(target)
155
155
156 for rev in sorted(state):
156 for rev in sorted(state):
157 if state[rev] == -1:
157 if state[rev] == -1:
158 ui.debug("rebasing %d:%s\n" % (rev, repo[rev]))
158 ui.debug("rebasing %d:%s\n" % (rev, repo[rev]))
159 storestatus(repo, originalwd, target, state, collapsef, keepf,
159 storestatus(repo, originalwd, target, state, collapsef, keepf,
160 keepbranchesf, external)
160 keepbranchesf, external)
161 p1, p2 = defineparents(repo, rev, target, state,
161 p1, p2 = defineparents(repo, rev, target, state,
162 targetancestors)
162 targetancestors)
163 if len(repo.parents()) == 2:
163 if len(repo.parents()) == 2:
164 repo.ui.debug('resuming interrupted rebase\n')
164 repo.ui.debug('resuming interrupted rebase\n')
165 else:
165 else:
166 stats = rebasenode(repo, rev, p1, p2, state)
166 stats = rebasenode(repo, rev, p1, p2, state)
167 if stats and stats[3] > 0:
167 if stats and stats[3] > 0:
168 raise util.Abort(_('fix unresolved conflicts with hg '
168 raise util.Abort(_('fix unresolved conflicts with hg '
169 'resolve then run hg rebase --continue'))
169 'resolve then run hg rebase --continue'))
170 updatedirstate(repo, rev, target, p2)
170 updatedirstate(repo, rev, target, p2)
171 if not collapsef:
171 if not collapsef:
172 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn)
172 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn)
173 else:
173 else:
174 # Skip commit if we are collapsing
174 # Skip commit if we are collapsing
175 repo.dirstate.setparents(repo[p1].node())
175 repo.dirstate.setparents(repo[p1].node())
176 newrev = None
176 newrev = None
177 # Update the state
177 # Update the state
178 if newrev is not None:
178 if newrev is not None:
179 state[rev] = repo[newrev].rev()
179 state[rev] = repo[newrev].rev()
180 else:
180 else:
181 if not collapsef:
181 if not collapsef:
182 ui.note(_('no changes, revision %d skipped\n') % rev)
182 ui.note(_('no changes, revision %d skipped\n') % rev)
183 ui.debug('next revision set to %s\n' % p1)
183 ui.debug('next revision set to %s\n' % p1)
184 skipped.add(rev)
184 skipped.add(rev)
185 state[rev] = p1
185 state[rev] = p1
186
186
187 ui.note(_('rebase merging completed\n'))
187 ui.note(_('rebase merging completed\n'))
188
188
189 if collapsef and not keepopen:
189 if collapsef and not keepopen:
190 p1, p2 = defineparents(repo, min(state), target,
190 p1, p2 = defineparents(repo, min(state), target,
191 state, targetancestors)
191 state, targetancestors)
192 commitmsg = 'Collapsed revision'
192 commitmsg = 'Collapsed revision'
193 for rebased in state:
193 for rebased in state:
194 if rebased not in skipped and state[rebased] != nullmerge:
194 if rebased not in skipped and state[rebased] != nullmerge:
195 commitmsg += '\n* %s' % repo[rebased].description()
195 commitmsg += '\n* %s' % repo[rebased].description()
196 commitmsg = ui.edit(commitmsg, repo.ui.username())
196 commitmsg = ui.edit(commitmsg, repo.ui.username())
197 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
197 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
198 extrafn=extrafn)
198 extrafn=extrafn)
199
199
200 if 'qtip' in repo.tags():
200 if 'qtip' in repo.tags():
201 updatemq(repo, state, skipped, **opts)
201 updatemq(repo, state, skipped, **opts)
202
202
203 if not keepf:
203 if not keepf:
204 # Remove no more useful revisions
204 # Remove no more useful revisions
205 rebased = [rev for rev in state if state[rev] != nullmerge]
205 rebased = [rev for rev in state if state[rev] != nullmerge]
206 if rebased:
206 if rebased:
207 if set(repo.changelog.descendants(min(rebased))) - set(state):
207 if set(repo.changelog.descendants(min(rebased))) - set(state):
208 ui.warn(_("warning: new changesets detected "
208 ui.warn(_("warning: new changesets detected "
209 "on source branch, not stripping\n"))
209 "on source branch, not stripping\n"))
210 else:
210 else:
211 repair.strip(ui, repo, repo[min(rebased)].node(), "strip")
211 # backup the old csets by default
212 repair.strip(ui, repo, repo[min(rebased)].node(), "all")
212
213
213 clearstatus(repo)
214 clearstatus(repo)
214 ui.status(_("rebase completed\n"))
215 ui.status(_("rebase completed\n"))
215 if os.path.exists(repo.sjoin('undo')):
216 if os.path.exists(repo.sjoin('undo')):
216 util.unlink(repo.sjoin('undo'))
217 util.unlink(repo.sjoin('undo'))
217 if skipped:
218 if skipped:
218 ui.note(_("%d revisions have been skipped\n") % len(skipped))
219 ui.note(_("%d revisions have been skipped\n") % len(skipped))
219 finally:
220 finally:
220 release(lock, wlock)
221 release(lock, wlock)
221
222
222 def rebasemerge(repo, rev, first=False):
223 def rebasemerge(repo, rev, first=False):
223 'return the correct ancestor'
224 'return the correct ancestor'
224 oldancestor = ancestor.ancestor
225 oldancestor = ancestor.ancestor
225
226
226 def newancestor(a, b, pfunc):
227 def newancestor(a, b, pfunc):
227 if b == rev:
228 if b == rev:
228 return repo[rev].parents()[0].rev()
229 return repo[rev].parents()[0].rev()
229 return oldancestor(a, b, pfunc)
230 return oldancestor(a, b, pfunc)
230
231
231 if not first:
232 if not first:
232 ancestor.ancestor = newancestor
233 ancestor.ancestor = newancestor
233 else:
234 else:
234 repo.ui.debug("first revision, do not change ancestor\n")
235 repo.ui.debug("first revision, do not change ancestor\n")
235 try:
236 try:
236 stats = merge.update(repo, rev, True, True, False)
237 stats = merge.update(repo, rev, True, True, False)
237 return stats
238 return stats
238 finally:
239 finally:
239 ancestor.ancestor = oldancestor
240 ancestor.ancestor = oldancestor
240
241
241 def checkexternal(repo, state, targetancestors):
242 def checkexternal(repo, state, targetancestors):
242 """Check whether one or more external revisions need to be taken in
243 """Check whether one or more external revisions need to be taken in
243 consideration. In the latter case, abort.
244 consideration. In the latter case, abort.
244 """
245 """
245 external = nullrev
246 external = nullrev
246 source = min(state)
247 source = min(state)
247 for rev in state:
248 for rev in state:
248 if rev == source:
249 if rev == source:
249 continue
250 continue
250 # Check externals and fail if there are more than one
251 # Check externals and fail if there are more than one
251 for p in repo[rev].parents():
252 for p in repo[rev].parents():
252 if (p.rev() not in state
253 if (p.rev() not in state
253 and p.rev() not in targetancestors):
254 and p.rev() not in targetancestors):
254 if external != nullrev:
255 if external != nullrev:
255 raise util.Abort(_('unable to collapse, there is more '
256 raise util.Abort(_('unable to collapse, there is more '
256 'than one external parent'))
257 'than one external parent'))
257 external = p.rev()
258 external = p.rev()
258 return external
259 return external
259
260
260 def updatedirstate(repo, rev, p1, p2):
261 def updatedirstate(repo, rev, p1, p2):
261 """Keep track of renamed files in the revision that is going to be rebased
262 """Keep track of renamed files in the revision that is going to be rebased
262 """
263 """
263 # Here we simulate the copies and renames in the source changeset
264 # Here we simulate the copies and renames in the source changeset
264 cop, diver = copies.copies(repo, repo[rev], repo[p1], repo[p2], True)
265 cop, diver = copies.copies(repo, repo[rev], repo[p1], repo[p2], True)
265 m1 = repo[rev].manifest()
266 m1 = repo[rev].manifest()
266 m2 = repo[p1].manifest()
267 m2 = repo[p1].manifest()
267 for k, v in cop.iteritems():
268 for k, v in cop.iteritems():
268 if k in m1:
269 if k in m1:
269 if v in m1 or v in m2:
270 if v in m1 or v in m2:
270 repo.dirstate.copy(v, k)
271 repo.dirstate.copy(v, k)
271 if v in m2 and v not in m1:
272 if v in m2 and v not in m1:
272 repo.dirstate.remove(v)
273 repo.dirstate.remove(v)
273
274
274 def concludenode(repo, rev, p1, p2, commitmsg=None, extrafn=None):
275 def concludenode(repo, rev, p1, p2, commitmsg=None, extrafn=None):
275 'Commit the changes and store useful information in extra'
276 'Commit the changes and store useful information in extra'
276 try:
277 try:
277 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
278 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
278 if commitmsg is None:
279 if commitmsg is None:
279 commitmsg = repo[rev].description()
280 commitmsg = repo[rev].description()
280 ctx = repo[rev]
281 ctx = repo[rev]
281 extra = {'rebase_source': ctx.hex()}
282 extra = {'rebase_source': ctx.hex()}
282 if extrafn:
283 if extrafn:
283 extrafn(ctx, extra)
284 extrafn(ctx, extra)
284 # Commit might fail if unresolved files exist
285 # Commit might fail if unresolved files exist
285 newrev = repo.commit(text=commitmsg, user=ctx.user(),
286 newrev = repo.commit(text=commitmsg, user=ctx.user(),
286 date=ctx.date(), extra=extra)
287 date=ctx.date(), extra=extra)
287 repo.dirstate.setbranch(repo[newrev].branch())
288 repo.dirstate.setbranch(repo[newrev].branch())
288 return newrev
289 return newrev
289 except util.Abort:
290 except util.Abort:
290 # Invalidate the previous setparents
291 # Invalidate the previous setparents
291 repo.dirstate.invalidate()
292 repo.dirstate.invalidate()
292 raise
293 raise
293
294
294 def rebasenode(repo, rev, p1, p2, state):
295 def rebasenode(repo, rev, p1, p2, state):
295 'Rebase a single revision'
296 'Rebase a single revision'
296 # Merge phase
297 # Merge phase
297 # Update to target and merge it with local
298 # Update to target and merge it with local
298 if repo['.'].rev() != repo[p1].rev():
299 if repo['.'].rev() != repo[p1].rev():
299 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
300 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
300 merge.update(repo, p1, False, True, False)
301 merge.update(repo, p1, False, True, False)
301 else:
302 else:
302 repo.ui.debug(" already in target\n")
303 repo.ui.debug(" already in target\n")
303 repo.dirstate.write()
304 repo.dirstate.write()
304 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
305 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
305 first = repo[rev].rev() == repo[min(state)].rev()
306 first = repo[rev].rev() == repo[min(state)].rev()
306 stats = rebasemerge(repo, rev, first)
307 stats = rebasemerge(repo, rev, first)
307 return stats
308 return stats
308
309
309 def defineparents(repo, rev, target, state, targetancestors):
310 def defineparents(repo, rev, target, state, targetancestors):
310 'Return the new parent relationship of the revision that will be rebased'
311 'Return the new parent relationship of the revision that will be rebased'
311 parents = repo[rev].parents()
312 parents = repo[rev].parents()
312 p1 = p2 = nullrev
313 p1 = p2 = nullrev
313
314
314 P1n = parents[0].rev()
315 P1n = parents[0].rev()
315 if P1n in targetancestors:
316 if P1n in targetancestors:
316 p1 = target
317 p1 = target
317 elif P1n in state:
318 elif P1n in state:
318 if state[P1n] == nullmerge:
319 if state[P1n] == nullmerge:
319 p1 = target
320 p1 = target
320 else:
321 else:
321 p1 = state[P1n]
322 p1 = state[P1n]
322 else: # P1n external
323 else: # P1n external
323 p1 = target
324 p1 = target
324 p2 = P1n
325 p2 = P1n
325
326
326 if len(parents) == 2 and parents[1].rev() not in targetancestors:
327 if len(parents) == 2 and parents[1].rev() not in targetancestors:
327 P2n = parents[1].rev()
328 P2n = parents[1].rev()
328 # interesting second parent
329 # interesting second parent
329 if P2n in state:
330 if P2n in state:
330 if p1 == target: # P1n in targetancestors or external
331 if p1 == target: # P1n in targetancestors or external
331 p1 = state[P2n]
332 p1 = state[P2n]
332 else:
333 else:
333 p2 = state[P2n]
334 p2 = state[P2n]
334 else: # P2n external
335 else: # P2n external
335 if p2 != nullrev: # P1n external too => rev is a merged revision
336 if p2 != nullrev: # P1n external too => rev is a merged revision
336 raise util.Abort(_('cannot use revision %d as base, result '
337 raise util.Abort(_('cannot use revision %d as base, result '
337 'would have 3 parents') % rev)
338 'would have 3 parents') % rev)
338 p2 = P2n
339 p2 = P2n
339 repo.ui.debug(" future parents are %d and %d\n" %
340 repo.ui.debug(" future parents are %d and %d\n" %
340 (repo[p1].rev(), repo[p2].rev()))
341 (repo[p1].rev(), repo[p2].rev()))
341 return p1, p2
342 return p1, p2
342
343
343 def isagitpatch(repo, patchname):
344 def isagitpatch(repo, patchname):
344 'Return true if the given patch is in git format'
345 'Return true if the given patch is in git format'
345 mqpatch = os.path.join(repo.mq.path, patchname)
346 mqpatch = os.path.join(repo.mq.path, patchname)
346 for line in patch.linereader(file(mqpatch, 'rb')):
347 for line in patch.linereader(file(mqpatch, 'rb')):
347 if line.startswith('diff --git'):
348 if line.startswith('diff --git'):
348 return True
349 return True
349 return False
350 return False
350
351
351 def updatemq(repo, state, skipped, **opts):
352 def updatemq(repo, state, skipped, **opts):
352 'Update rebased mq patches - finalize and then import them'
353 'Update rebased mq patches - finalize and then import them'
353 mqrebase = {}
354 mqrebase = {}
354 for p in repo.mq.applied:
355 for p in repo.mq.applied:
355 if repo[p.node].rev() in state:
356 if repo[p.node].rev() in state:
356 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
357 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
357 (repo[p.node].rev(), p.name))
358 (repo[p.node].rev(), p.name))
358 mqrebase[repo[p.node].rev()] = (p.name, isagitpatch(repo, p.name))
359 mqrebase[repo[p.node].rev()] = (p.name, isagitpatch(repo, p.name))
359
360
360 if mqrebase:
361 if mqrebase:
361 repo.mq.finish(repo, mqrebase.keys())
362 repo.mq.finish(repo, mqrebase.keys())
362
363
363 # We must start import from the newest revision
364 # We must start import from the newest revision
364 for rev in sorted(mqrebase, reverse=True):
365 for rev in sorted(mqrebase, reverse=True):
365 if rev not in skipped:
366 if rev not in skipped:
366 repo.ui.debug('import mq patch %d (%s)\n'
367 repo.ui.debug('import mq patch %d (%s)\n'
367 % (state[rev], mqrebase[rev][0]))
368 % (state[rev], mqrebase[rev][0]))
368 repo.mq.qimport(repo, (), patchname=mqrebase[rev][0],
369 repo.mq.qimport(repo, (), patchname=mqrebase[rev][0],
369 git=mqrebase[rev][1],rev=[str(state[rev])])
370 git=mqrebase[rev][1],rev=[str(state[rev])])
370 repo.mq.save_dirty()
371 repo.mq.save_dirty()
371
372
372 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
373 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
373 external):
374 external):
374 'Store the current status to allow recovery'
375 'Store the current status to allow recovery'
375 f = repo.opener("rebasestate", "w")
376 f = repo.opener("rebasestate", "w")
376 f.write(repo[originalwd].hex() + '\n')
377 f.write(repo[originalwd].hex() + '\n')
377 f.write(repo[target].hex() + '\n')
378 f.write(repo[target].hex() + '\n')
378 f.write(repo[external].hex() + '\n')
379 f.write(repo[external].hex() + '\n')
379 f.write('%d\n' % int(collapse))
380 f.write('%d\n' % int(collapse))
380 f.write('%d\n' % int(keep))
381 f.write('%d\n' % int(keep))
381 f.write('%d\n' % int(keepbranches))
382 f.write('%d\n' % int(keepbranches))
382 for d, v in state.iteritems():
383 for d, v in state.iteritems():
383 oldrev = repo[d].hex()
384 oldrev = repo[d].hex()
384 newrev = repo[v].hex()
385 newrev = repo[v].hex()
385 f.write("%s:%s\n" % (oldrev, newrev))
386 f.write("%s:%s\n" % (oldrev, newrev))
386 f.close()
387 f.close()
387 repo.ui.debug('rebase status stored\n')
388 repo.ui.debug('rebase status stored\n')
388
389
389 def clearstatus(repo):
390 def clearstatus(repo):
390 'Remove the status files'
391 'Remove the status files'
391 if os.path.exists(repo.join("rebasestate")):
392 if os.path.exists(repo.join("rebasestate")):
392 util.unlink(repo.join("rebasestate"))
393 util.unlink(repo.join("rebasestate"))
393
394
394 def restorestatus(repo):
395 def restorestatus(repo):
395 'Restore a previously stored status'
396 'Restore a previously stored status'
396 try:
397 try:
397 target = None
398 target = None
398 collapse = False
399 collapse = False
399 external = nullrev
400 external = nullrev
400 state = {}
401 state = {}
401 f = repo.opener("rebasestate")
402 f = repo.opener("rebasestate")
402 for i, l in enumerate(f.read().splitlines()):
403 for i, l in enumerate(f.read().splitlines()):
403 if i == 0:
404 if i == 0:
404 originalwd = repo[l].rev()
405 originalwd = repo[l].rev()
405 elif i == 1:
406 elif i == 1:
406 target = repo[l].rev()
407 target = repo[l].rev()
407 elif i == 2:
408 elif i == 2:
408 external = repo[l].rev()
409 external = repo[l].rev()
409 elif i == 3:
410 elif i == 3:
410 collapse = bool(int(l))
411 collapse = bool(int(l))
411 elif i == 4:
412 elif i == 4:
412 keep = bool(int(l))
413 keep = bool(int(l))
413 elif i == 5:
414 elif i == 5:
414 keepbranches = bool(int(l))
415 keepbranches = bool(int(l))
415 else:
416 else:
416 oldrev, newrev = l.split(':')
417 oldrev, newrev = l.split(':')
417 state[repo[oldrev].rev()] = repo[newrev].rev()
418 state[repo[oldrev].rev()] = repo[newrev].rev()
418 repo.ui.debug('rebase status resumed\n')
419 repo.ui.debug('rebase status resumed\n')
419 return originalwd, target, state, collapse, keep, keepbranches, external
420 return originalwd, target, state, collapse, keep, keepbranches, external
420 except IOError, err:
421 except IOError, err:
421 if err.errno != errno.ENOENT:
422 if err.errno != errno.ENOENT:
422 raise
423 raise
423 raise util.Abort(_('no rebase in progress'))
424 raise util.Abort(_('no rebase in progress'))
424
425
425 def abort(repo, originalwd, target, state):
426 def abort(repo, originalwd, target, state):
426 'Restore the repository to its original state'
427 'Restore the repository to its original state'
427 if set(repo.changelog.descendants(target)) - set(state.values()):
428 if set(repo.changelog.descendants(target)) - set(state.values()):
428 repo.ui.warn(_("warning: new changesets detected on target branch, "
429 repo.ui.warn(_("warning: new changesets detected on target branch, "
429 "not stripping\n"))
430 "not stripping\n"))
430 else:
431 else:
431 # Strip from the first rebased revision
432 # Strip from the first rebased revision
432 merge.update(repo, repo[originalwd].rev(), False, True, False)
433 merge.update(repo, repo[originalwd].rev(), False, True, False)
433 rebased = filter(lambda x: x > -1, state.values())
434 rebased = filter(lambda x: x > -1, state.values())
434 if rebased:
435 if rebased:
435 strippoint = min(rebased)
436 strippoint = min(rebased)
436 repair.strip(repo.ui, repo, repo[strippoint].node(), "strip")
437 # no backup of rebased cset versions needed
438 repair.strip(repo.ui, repo, repo[strippoint].node())
437 clearstatus(repo)
439 clearstatus(repo)
438 repo.ui.status(_('rebase aborted\n'))
440 repo.ui.status(_('rebase aborted\n'))
439
441
440 def buildstate(repo, dest, src, base, detach):
442 def buildstate(repo, dest, src, base, detach):
441 'Define which revisions are going to be rebased and where'
443 'Define which revisions are going to be rebased and where'
442 targetancestors = set()
444 targetancestors = set()
443 detachset = set()
445 detachset = set()
444
446
445 if not dest:
447 if not dest:
446 # Destination defaults to the latest revision in the current branch
448 # Destination defaults to the latest revision in the current branch
447 branch = repo[None].branch()
449 branch = repo[None].branch()
448 dest = repo[branch].rev()
450 dest = repo[branch].rev()
449 else:
451 else:
450 dest = repo[dest].rev()
452 dest = repo[dest].rev()
451
453
452 # This check isn't strictly necessary, since mq detects commits over an
454 # This check isn't strictly necessary, since mq detects commits over an
453 # applied patch. But it prevents messing up the working directory when
455 # applied patch. But it prevents messing up the working directory when
454 # a partially completed rebase is blocked by mq.
456 # a partially completed rebase is blocked by mq.
455 if 'qtip' in repo.tags() and (repo[dest].node() in
457 if 'qtip' in repo.tags() and (repo[dest].node() in
456 [s.node for s in repo.mq.applied]):
458 [s.node for s in repo.mq.applied]):
457 raise util.Abort(_('cannot rebase onto an applied mq patch'))
459 raise util.Abort(_('cannot rebase onto an applied mq patch'))
458
460
459 if src:
461 if src:
460 commonbase = repo[src].ancestor(repo[dest])
462 commonbase = repo[src].ancestor(repo[dest])
461 if commonbase == repo[src]:
463 if commonbase == repo[src]:
462 raise util.Abort(_('source is ancestor of destination'))
464 raise util.Abort(_('source is ancestor of destination'))
463 if commonbase == repo[dest]:
465 if commonbase == repo[dest]:
464 raise util.Abort(_('source is descendant of destination'))
466 raise util.Abort(_('source is descendant of destination'))
465 source = repo[src].rev()
467 source = repo[src].rev()
466 if detach:
468 if detach:
467 # We need to keep track of source's ancestors up to the common base
469 # We need to keep track of source's ancestors up to the common base
468 srcancestors = set(repo.changelog.ancestors(source))
470 srcancestors = set(repo.changelog.ancestors(source))
469 baseancestors = set(repo.changelog.ancestors(commonbase.rev()))
471 baseancestors = set(repo.changelog.ancestors(commonbase.rev()))
470 detachset = srcancestors - baseancestors
472 detachset = srcancestors - baseancestors
471 detachset.remove(commonbase.rev())
473 detachset.remove(commonbase.rev())
472 else:
474 else:
473 if base:
475 if base:
474 cwd = repo[base].rev()
476 cwd = repo[base].rev()
475 else:
477 else:
476 cwd = repo['.'].rev()
478 cwd = repo['.'].rev()
477
479
478 if cwd == dest:
480 if cwd == dest:
479 repo.ui.debug('source and destination are the same\n')
481 repo.ui.debug('source and destination are the same\n')
480 return None
482 return None
481
483
482 targetancestors = set(repo.changelog.ancestors(dest))
484 targetancestors = set(repo.changelog.ancestors(dest))
483 if cwd in targetancestors:
485 if cwd in targetancestors:
484 repo.ui.debug('source is ancestor of destination\n')
486 repo.ui.debug('source is ancestor of destination\n')
485 return None
487 return None
486
488
487 cwdancestors = set(repo.changelog.ancestors(cwd))
489 cwdancestors = set(repo.changelog.ancestors(cwd))
488 if dest in cwdancestors:
490 if dest in cwdancestors:
489 repo.ui.debug('source is descendant of destination\n')
491 repo.ui.debug('source is descendant of destination\n')
490 return None
492 return None
491
493
492 cwdancestors.add(cwd)
494 cwdancestors.add(cwd)
493 rebasingbranch = cwdancestors - targetancestors
495 rebasingbranch = cwdancestors - targetancestors
494 source = min(rebasingbranch)
496 source = min(rebasingbranch)
495
497
496 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, source))
498 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, source))
497 state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
499 state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
498 state.update(dict.fromkeys(detachset, nullmerge))
500 state.update(dict.fromkeys(detachset, nullmerge))
499 state[source] = nullrev
501 state[source] = nullrev
500 return repo['.'].rev(), repo[dest].rev(), state
502 return repo['.'].rev(), repo[dest].rev(), state
501
503
502 def pullrebase(orig, ui, repo, *args, **opts):
504 def pullrebase(orig, ui, repo, *args, **opts):
503 'Call rebase after pull if the latter has been invoked with --rebase'
505 'Call rebase after pull if the latter has been invoked with --rebase'
504 if opts.get('rebase'):
506 if opts.get('rebase'):
505 if opts.get('update'):
507 if opts.get('update'):
506 del opts['update']
508 del opts['update']
507 ui.debug('--update and --rebase are not compatible, ignoring '
509 ui.debug('--update and --rebase are not compatible, ignoring '
508 'the update flag\n')
510 'the update flag\n')
509
511
510 cmdutil.bail_if_changed(repo)
512 cmdutil.bail_if_changed(repo)
511 revsprepull = len(repo)
513 revsprepull = len(repo)
512 origpostincoming = commands.postincoming
514 origpostincoming = commands.postincoming
513 def _dummy(*args, **kwargs):
515 def _dummy(*args, **kwargs):
514 pass
516 pass
515 commands.postincoming = _dummy
517 commands.postincoming = _dummy
516 try:
518 try:
517 orig(ui, repo, *args, **opts)
519 orig(ui, repo, *args, **opts)
518 finally:
520 finally:
519 commands.postincoming = origpostincoming
521 commands.postincoming = origpostincoming
520 revspostpull = len(repo)
522 revspostpull = len(repo)
521 if revspostpull > revsprepull:
523 if revspostpull > revsprepull:
522 rebase(ui, repo, **opts)
524 rebase(ui, repo, **opts)
523 branch = repo[None].branch()
525 branch = repo[None].branch()
524 dest = repo[branch].rev()
526 dest = repo[branch].rev()
525 if dest != repo['.'].rev():
527 if dest != repo['.'].rev():
526 # there was nothing to rebase we force an update
528 # there was nothing to rebase we force an update
527 hg.update(repo, dest)
529 hg.update(repo, dest)
528 else:
530 else:
529 orig(ui, repo, *args, **opts)
531 orig(ui, repo, *args, **opts)
530
532
531 def uisetup(ui):
533 def uisetup(ui):
532 'Replace pull with a decorator to provide --rebase option'
534 'Replace pull with a decorator to provide --rebase option'
533 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
535 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
534 entry[1].append(('', 'rebase', None,
536 entry[1].append(('', 'rebase', None,
535 _("rebase working directory to branch head"))
537 _("rebase working directory to branch head"))
536 )
538 )
537
539
538 cmdtable = {
540 cmdtable = {
539 "rebase":
541 "rebase":
540 (rebase,
542 (rebase,
541 [
543 [
542 ('s', 'source', '', _('rebase from the specified changeset')),
544 ('s', 'source', '', _('rebase from the specified changeset')),
543 ('b', 'base', '', _('rebase from the base of the specified changeset '
545 ('b', 'base', '', _('rebase from the base of the specified changeset '
544 '(up to greatest common ancestor of base and dest)')),
546 '(up to greatest common ancestor of base and dest)')),
545 ('d', 'dest', '', _('rebase onto the specified changeset')),
547 ('d', 'dest', '', _('rebase onto the specified changeset')),
546 ('', 'collapse', False, _('collapse the rebased changesets')),
548 ('', 'collapse', False, _('collapse the rebased changesets')),
547 ('', 'keep', False, _('keep original changesets')),
549 ('', 'keep', False, _('keep original changesets')),
548 ('', 'keepbranches', False, _('keep original branch names')),
550 ('', 'keepbranches', False, _('keep original branch names')),
549 ('', 'detach', False, _('force detaching of source from its original '
551 ('', 'detach', False, _('force detaching of source from its original '
550 'branch')),
552 'branch')),
551 ('c', 'continue', False, _('continue an interrupted rebase')),
553 ('c', 'continue', False, _('continue an interrupted rebase')),
552 ('a', 'abort', False, _('abort an interrupted rebase'))] +
554 ('a', 'abort', False, _('abort an interrupted rebase'))] +
553 templateopts,
555 templateopts,
554 _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
556 _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
555 'hg rebase {-a|-c}'))
557 'hg rebase {-a|-c}'))
556 }
558 }
@@ -1,43 +1,44 b''
1 % initialize repository
1 % initialize repository
2 adding a
2 adding a
3 adding b
3 adding b
4 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
4 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
5 adding c
5 adding c
6 created new head
6 created new head
7 adding d
7 adding d
8 % bookmark list
8 % bookmark list
9 * two 3:2ae46b1d99a7
9 * two 3:2ae46b1d99a7
10 one 1:925d80f479bb
10 one 1:925d80f479bb
11 % rebase
11 % rebase
12 saved backup bundle to
12 adding branch
13 adding branch
13 adding changesets
14 adding changesets
14 adding manifests
15 adding manifests
15 adding file changes
16 adding file changes
16 added 1 changesets with 1 changes to 1 files (-1 heads)
17 added 1 changesets with 1 changes to 1 files (-1 heads)
17 rebase completed
18 rebase completed
18 changeset: 3:9163974d1cb5
19 changeset: 3:9163974d1cb5
19 tag: one
20 tag: one
20 tag: tip
21 tag: tip
21 tag: two
22 tag: two
22 parent: 1:925d80f479bb
23 parent: 1:925d80f479bb
23 parent: 2:db815d6d32e6
24 parent: 2:db815d6d32e6
24 user: test
25 user: test
25 date: Thu Jan 01 00:00:00 1970 +0000
26 date: Thu Jan 01 00:00:00 1970 +0000
26 summary: 3
27 summary: 3
27
28
28 changeset: 2:db815d6d32e6
29 changeset: 2:db815d6d32e6
29 parent: 0:f7b1eb17ad24
30 parent: 0:f7b1eb17ad24
30 user: test
31 user: test
31 date: Thu Jan 01 00:00:00 1970 +0000
32 date: Thu Jan 01 00:00:00 1970 +0000
32 summary: 2
33 summary: 2
33
34
34 changeset: 1:925d80f479bb
35 changeset: 1:925d80f479bb
35 user: test
36 user: test
36 date: Thu Jan 01 00:00:00 1970 +0000
37 date: Thu Jan 01 00:00:00 1970 +0000
37 summary: 1
38 summary: 1
38
39
39 changeset: 0:f7b1eb17ad24
40 changeset: 0:f7b1eb17ad24
40 user: test
41 user: test
41 date: Thu Jan 01 00:00:00 1970 +0000
42 date: Thu Jan 01 00:00:00 1970 +0000
42 summary: 0
43 summary: 0
43
44
@@ -1,31 +1,32 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 created new head
2 created new head
3 @ 4: L2
3 @ 4: L2
4 |
4 |
5 o 3: L1
5 o 3: L1
6 |
6 |
7 | o 2: C3
7 | o 2: C3
8 |/
8 |/
9 o 1: C2
9 o 1: C2
10 |
10 |
11 o 0: C1
11 o 0: C1
12
12
13
13
14 % Conflicting rebase
14 % Conflicting rebase
15 warning: conflicts during merge.
15 warning: conflicts during merge.
16 merging common failed!
16 merging common failed!
17 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
17 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
18 merging common
18 merging common
19
19
20 % Abort
20 % Abort
21 saved backup bundle to
21 rebase aborted
22 rebase aborted
22 @ 4: L2
23 @ 4: L2
23 |
24 |
24 o 3: L1
25 o 3: L1
25 |
26 |
26 | o 2: C3
27 | o 2: C3
27 |/
28 |/
28 o 1: C2
29 o 1: C2
29 |
30 |
30 o 0: C1
31 o 0: C1
31
32
@@ -1,183 +1,186 b''
1
1
2 @ 8:c11d5b3e9c00 F branch: branch3
2 @ 8:c11d5b3e9c00 F branch: branch3
3 |
3 |
4 o 7:33c9da881988 Branch3 branch: branch3
4 o 7:33c9da881988 Branch3 branch: branch3
5 |
5 |
6 | o 6:0e4064ab11a3 E branch: branch2
6 | o 6:0e4064ab11a3 E branch: branch2
7 | |
7 | |
8 | o 5:5ac035cb5d8f D branch: branch2
8 | o 5:5ac035cb5d8f D branch: branch2
9 | |
9 | |
10 | | o 4:8e66061486ee C branch: branch2
10 | | o 4:8e66061486ee C branch: branch2
11 | | |
11 | | |
12 +---o 3:99567862abbe Branch2 branch: branch2
12 +---o 3:99567862abbe Branch2 branch: branch2
13 | |
13 | |
14 | o 2:65a26a4d12f6 B branch: branch1
14 | o 2:65a26a4d12f6 B branch: branch1
15 | |
15 | |
16 | o 1:0f3f3010ee16 Branch1 branch: branch1
16 | o 1:0f3f3010ee16 Branch1 branch: branch1
17 |/
17 |/
18 o 0:1994f17a630e A branch:
18 o 0:1994f17a630e A branch:
19
19
20
20
21 % Branches
21 % Branches
22 branch3 8:c11d5b3e9c00
22 branch3 8:c11d5b3e9c00
23 branch2 6:0e4064ab11a3
23 branch2 6:0e4064ab11a3
24 branch1 2:65a26a4d12f6 (inactive)
24 branch1 2:65a26a4d12f6 (inactive)
25 default 0:1994f17a630e (inactive)
25 default 0:1994f17a630e (inactive)
26
26
27 % Heads
27 % Heads
28 8:c11d5b3e9c00 F branch: branch3
28 8:c11d5b3e9c00 F branch: branch3
29 6:0e4064ab11a3 E branch: branch2
29 6:0e4064ab11a3 E branch: branch2
30 4:8e66061486ee C branch: branch2
30 4:8e66061486ee C branch: branch2
31 2:65a26a4d12f6 B branch: branch1
31 2:65a26a4d12f6 B branch: branch1
32 0:1994f17a630e A branch:
32 0:1994f17a630e A branch:
33
33
34 % Rebase part of branch2 (5-6) onto branch3 (8)
34 % Rebase part of branch2 (5-6) onto branch3 (8)
35 saved backup bundle to
35 adding branch
36 adding branch
36 adding changesets
37 adding changesets
37 adding manifests
38 adding manifests
38 adding file changes
39 adding file changes
39 added 4 changesets with 3 changes to 3 files (+1 heads)
40 added 4 changesets with 3 changes to 3 files (+1 heads)
40 rebase completed
41 rebase completed
41
42
42 % Branches
43 % Branches
43 branch3 8:c9bfa9beb84e
44 branch3 8:c9bfa9beb84e
44 branch2 4:8e66061486ee
45 branch2 4:8e66061486ee
45 branch1 2:65a26a4d12f6
46 branch1 2:65a26a4d12f6
46 default 0:1994f17a630e (inactive)
47 default 0:1994f17a630e (inactive)
47
48
48 % Heads
49 % Heads
49 8:c9bfa9beb84e E branch: branch3
50 8:c9bfa9beb84e E branch: branch3
50 4:8e66061486ee C branch: branch2
51 4:8e66061486ee C branch: branch2
51 2:65a26a4d12f6 B branch: branch1
52 2:65a26a4d12f6 B branch: branch1
52 0:1994f17a630e A branch:
53 0:1994f17a630e A branch:
53
54
54 @ 8:c9bfa9beb84e E branch: branch3
55 @ 8:c9bfa9beb84e E branch: branch3
55 |
56 |
56 o 7:bf9037384081 D branch: branch3
57 o 7:bf9037384081 D branch: branch3
57 |
58 |
58 o 6:c11d5b3e9c00 F branch: branch3
59 o 6:c11d5b3e9c00 F branch: branch3
59 |
60 |
60 o 5:33c9da881988 Branch3 branch: branch3
61 o 5:33c9da881988 Branch3 branch: branch3
61 |
62 |
62 | o 4:8e66061486ee C branch: branch2
63 | o 4:8e66061486ee C branch: branch2
63 | |
64 | |
64 | o 3:99567862abbe Branch2 branch: branch2
65 | o 3:99567862abbe Branch2 branch: branch2
65 |/
66 |/
66 | o 2:65a26a4d12f6 B branch: branch1
67 | o 2:65a26a4d12f6 B branch: branch1
67 | |
68 | |
68 | o 1:0f3f3010ee16 Branch1 branch: branch1
69 | o 1:0f3f3010ee16 Branch1 branch: branch1
69 |/
70 |/
70 o 0:1994f17a630e A branch:
71 o 0:1994f17a630e A branch:
71
72
72
73
73 % Rebase head of branch3 (8) onto branch2 (6)
74 % Rebase head of branch3 (8) onto branch2 (6)
74 @ 8:c11d5b3e9c00 F branch: branch3
75 @ 8:c11d5b3e9c00 F branch: branch3
75 |
76 |
76 o 7:33c9da881988 Branch3 branch: branch3
77 o 7:33c9da881988 Branch3 branch: branch3
77 |
78 |
78 | o 6:0e4064ab11a3 E branch: branch2
79 | o 6:0e4064ab11a3 E branch: branch2
79 | |
80 | |
80 | o 5:5ac035cb5d8f D branch: branch2
81 | o 5:5ac035cb5d8f D branch: branch2
81 | |
82 | |
82 | | o 4:8e66061486ee C branch: branch2
83 | | o 4:8e66061486ee C branch: branch2
83 | | |
84 | | |
84 +---o 3:99567862abbe Branch2 branch: branch2
85 +---o 3:99567862abbe Branch2 branch: branch2
85 | |
86 | |
86 | o 2:65a26a4d12f6 B branch: branch1
87 | o 2:65a26a4d12f6 B branch: branch1
87 | |
88 | |
88 | o 1:0f3f3010ee16 Branch1 branch: branch1
89 | o 1:0f3f3010ee16 Branch1 branch: branch1
89 |/
90 |/
90 o 0:1994f17a630e A branch:
91 o 0:1994f17a630e A branch:
91
92
93 saved backup bundle to
92 adding branch
94 adding branch
93 adding changesets
95 adding changesets
94 adding manifests
96 adding manifests
95 adding file changes
97 adding file changes
96 added 1 changesets with 1 changes to 1 files
98 added 1 changesets with 1 changes to 1 files
97 rebase completed
99 rebase completed
98
100
99 % Branches
101 % Branches
100 branch2 8:b44d3024f247
102 branch2 8:b44d3024f247
101 branch3 7:33c9da881988
103 branch3 7:33c9da881988
102 branch1 2:65a26a4d12f6 (inactive)
104 branch1 2:65a26a4d12f6 (inactive)
103 default 0:1994f17a630e (inactive)
105 default 0:1994f17a630e (inactive)
104
106
105 % Heads
107 % Heads
106 8:b44d3024f247 F branch: branch2
108 8:b44d3024f247 F branch: branch2
107 7:33c9da881988 Branch3 branch: branch3
109 7:33c9da881988 Branch3 branch: branch3
108 4:8e66061486ee C branch: branch2
110 4:8e66061486ee C branch: branch2
109 2:65a26a4d12f6 B branch: branch1
111 2:65a26a4d12f6 B branch: branch1
110 0:1994f17a630e A branch:
112 0:1994f17a630e A branch:
111
113
112 @ 8:b44d3024f247 F branch: branch2
114 @ 8:b44d3024f247 F branch: branch2
113 |
115 |
114 | o 7:33c9da881988 Branch3 branch: branch3
116 | o 7:33c9da881988 Branch3 branch: branch3
115 | |
117 | |
116 o | 6:0e4064ab11a3 E branch: branch2
118 o | 6:0e4064ab11a3 E branch: branch2
117 | |
119 | |
118 o | 5:5ac035cb5d8f D branch: branch2
120 o | 5:5ac035cb5d8f D branch: branch2
119 | |
121 | |
120 | | o 4:8e66061486ee C branch: branch2
122 | | o 4:8e66061486ee C branch: branch2
121 | | |
123 | | |
122 | | o 3:99567862abbe Branch2 branch: branch2
124 | | o 3:99567862abbe Branch2 branch: branch2
123 | |/
125 | |/
124 o | 2:65a26a4d12f6 B branch: branch1
126 o | 2:65a26a4d12f6 B branch: branch1
125 | |
127 | |
126 o | 1:0f3f3010ee16 Branch1 branch: branch1
128 o | 1:0f3f3010ee16 Branch1 branch: branch1
127 |/
129 |/
128 o 0:1994f17a630e A branch:
130 o 0:1994f17a630e A branch:
129
131
130
132
131 % Rebase entire branch3 (7-8) onto branch2 (6)
133 % Rebase entire branch3 (7-8) onto branch2 (6)
132 @ 8:c11d5b3e9c00 F branch: branch3
134 @ 8:c11d5b3e9c00 F branch: branch3
133 |
135 |
134 o 7:33c9da881988 Branch3 branch: branch3
136 o 7:33c9da881988 Branch3 branch: branch3
135 |
137 |
136 | o 6:0e4064ab11a3 E branch: branch2
138 | o 6:0e4064ab11a3 E branch: branch2
137 | |
139 | |
138 | o 5:5ac035cb5d8f D branch: branch2
140 | o 5:5ac035cb5d8f D branch: branch2
139 | |
141 | |
140 | | o 4:8e66061486ee C branch: branch2
142 | | o 4:8e66061486ee C branch: branch2
141 | | |
143 | | |
142 +---o 3:99567862abbe Branch2 branch: branch2
144 +---o 3:99567862abbe Branch2 branch: branch2
143 | |
145 | |
144 | o 2:65a26a4d12f6 B branch: branch1
146 | o 2:65a26a4d12f6 B branch: branch1
145 | |
147 | |
146 | o 1:0f3f3010ee16 Branch1 branch: branch1
148 | o 1:0f3f3010ee16 Branch1 branch: branch1
147 |/
149 |/
148 o 0:1994f17a630e A branch:
150 o 0:1994f17a630e A branch:
149
151
152 saved backup bundle to
150 adding branch
153 adding branch
151 adding changesets
154 adding changesets
152 adding manifests
155 adding manifests
153 adding file changes
156 adding file changes
154 added 1 changesets with 1 changes to 1 files
157 added 1 changesets with 1 changes to 1 files
155 rebase completed
158 rebase completed
156
159
157 % Branches
160 % Branches
158 branch2 7:b44d3024f247
161 branch2 7:b44d3024f247
159 branch1 2:65a26a4d12f6 (inactive)
162 branch1 2:65a26a4d12f6 (inactive)
160 default 0:1994f17a630e (inactive)
163 default 0:1994f17a630e (inactive)
161
164
162 % Heads
165 % Heads
163 7:b44d3024f247 F branch: branch2
166 7:b44d3024f247 F branch: branch2
164 4:8e66061486ee C branch: branch2
167 4:8e66061486ee C branch: branch2
165 2:65a26a4d12f6 B branch: branch1
168 2:65a26a4d12f6 B branch: branch1
166 0:1994f17a630e A branch:
169 0:1994f17a630e A branch:
167
170
168 @ 7:b44d3024f247 F branch: branch2
171 @ 7:b44d3024f247 F branch: branch2
169 |
172 |
170 o 6:0e4064ab11a3 E branch: branch2
173 o 6:0e4064ab11a3 E branch: branch2
171 |
174 |
172 o 5:5ac035cb5d8f D branch: branch2
175 o 5:5ac035cb5d8f D branch: branch2
173 |
176 |
174 | o 4:8e66061486ee C branch: branch2
177 | o 4:8e66061486ee C branch: branch2
175 | |
178 | |
176 | o 3:99567862abbe Branch2 branch: branch2
179 | o 3:99567862abbe Branch2 branch: branch2
177 | |
180 | |
178 o | 2:65a26a4d12f6 B branch: branch1
181 o | 2:65a26a4d12f6 B branch: branch1
179 | |
182 | |
180 o | 1:0f3f3010ee16 Branch1 branch: branch1
183 o | 1:0f3f3010ee16 Branch1 branch: branch1
181 |/
184 |/
182 o 0:1994f17a630e A branch:
185 o 0:1994f17a630e A branch:
183
186
@@ -1,75 +1,76 b''
1
1
2 % - Rebasing B onto E - check keep
2 % - Rebasing B onto E - check keep
3 @ 5:F:notdefault
3 @ 5:F:notdefault
4 |
4 |
5 | o 4:E:
5 | o 4:E:
6 | |
6 | |
7 | o 3:D:
7 | o 3:D:
8 |/
8 |/
9 | o 2:C:
9 | o 2:C:
10 | |
10 | |
11 | o 1:B:
11 | o 1:B:
12 |/
12 |/
13 o 0:A:
13 o 0:A:
14
14
15 warning: conflicts during merge.
15 warning: conflicts during merge.
16 merging A failed!
16 merging A failed!
17 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
17 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
18 merging A
18 merging A
19
19
20 % - Solve the conflict and go on
20 % - Solve the conflict and go on
21 rebase completed
21 rebase completed
22 @ 7:C:
22 @ 7:C:
23 |
23 |
24 o 6:B:
24 o 6:B:
25 |
25 |
26 | o 5:F:notdefault
26 | o 5:F:notdefault
27 | |
27 | |
28 o | 4:E:
28 o | 4:E:
29 | |
29 | |
30 o | 3:D:
30 o | 3:D:
31 |/
31 |/
32 | o 2:C:
32 | o 2:C:
33 | |
33 | |
34 | o 1:B:
34 | o 1:B:
35 |/
35 |/
36 o 0:A:
36 o 0:A:
37
37
38
38
39 % - Rebase F onto E - check keepbranches
39 % - Rebase F onto E - check keepbranches
40 @ 5:F:notdefault
40 @ 5:F:notdefault
41 |
41 |
42 | o 4:E:
42 | o 4:E:
43 | |
43 | |
44 | o 3:D:
44 | o 3:D:
45 |/
45 |/
46 | o 2:C:
46 | o 2:C:
47 | |
47 | |
48 | o 1:B:
48 | o 1:B:
49 |/
49 |/
50 o 0:A:
50 o 0:A:
51
51
52 warning: conflicts during merge.
52 warning: conflicts during merge.
53 merging A failed!
53 merging A failed!
54 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
54 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
55 merging A
55 merging A
56
56
57 % - Solve the conflict and go on
57 % - Solve the conflict and go on
58 saved backup bundle to
58 adding branch
59 adding branch
59 adding changesets
60 adding changesets
60 adding manifests
61 adding manifests
61 adding file changes
62 adding file changes
62 added 1 changesets with 1 changes to 1 files
63 added 1 changesets with 1 changes to 1 files
63 rebase completed
64 rebase completed
64 @ 5:F:notdefault
65 @ 5:F:notdefault
65 |
66 |
66 o 4:E:
67 o 4:E:
67 |
68 |
68 o 3:D:
69 o 3:D:
69 |
70 |
70 | o 2:C:
71 | o 2:C:
71 | |
72 | |
72 | o 1:B:
73 | o 1:B:
73 |/
74 |/
74 o 0:A:
75 o 0:A:
75
76
@@ -1,210 +1,215 b''
1 @ 7: H
1 @ 7: H
2 |
2 |
3 | o 6: G
3 | o 6: G
4 |/|
4 |/|
5 o | 5: F
5 o | 5: F
6 | |
6 | |
7 | o 4: E
7 | o 4: E
8 |/
8 |/
9 | o 3: D
9 | o 3: D
10 | |
10 | |
11 | o 2: C
11 | o 2: C
12 | |
12 | |
13 | o 1: B
13 | o 1: B
14 |/
14 |/
15 o 0: A
15 o 0: A
16
16
17 % Rebasing B onto H
17 % Rebasing B onto H
18 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
18 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
19 saved backup bundle to
19 adding branch
20 adding branch
20 adding changesets
21 adding changesets
21 adding manifests
22 adding manifests
22 adding file changes
23 adding file changes
23 added 5 changesets with 6 changes to 6 files (+1 heads)
24 added 5 changesets with 6 changes to 6 files (+1 heads)
24 rebase completed
25 rebase completed
25 @ 5: Collapsed revision
26 @ 5: Collapsed revision
26 | * B
27 | * B
27 | * C
28 | * C
28 | * D
29 | * D
29 o 4: H
30 o 4: H
30 |
31 |
31 | o 3: G
32 | o 3: G
32 |/|
33 |/|
33 o | 2: F
34 o | 2: F
34 | |
35 | |
35 | o 1: E
36 | o 1: E
36 |/
37 |/
37 o 0: A
38 o 0: A
38
39
39 Expected A, B, C, D, F, H
40 Expected A, B, C, D, F, H
40 A
41 A
41 B
42 B
42 C
43 C
43 D
44 D
44 F
45 F
45 H
46 H
46
47
47 % Rebasing G onto H
48 % Rebasing G onto H
49 saved backup bundle to
48 adding branch
50 adding branch
49 adding changesets
51 adding changesets
50 adding manifests
52 adding manifests
51 adding file changes
53 adding file changes
52 added 3 changesets with 3 changes to 3 files (+1 heads)
54 added 3 changesets with 3 changes to 3 files (+1 heads)
53 rebase completed
55 rebase completed
54 @ 6: Collapsed revision
56 @ 6: Collapsed revision
55 | * E
57 | * E
56 | * G
58 | * G
57 o 5: H
59 o 5: H
58 |
60 |
59 o 4: F
61 o 4: F
60 |
62 |
61 | o 3: D
63 | o 3: D
62 | |
64 | |
63 | o 2: C
65 | o 2: C
64 | |
66 | |
65 | o 1: B
67 | o 1: B
66 |/
68 |/
67 o 0: A
69 o 0: A
68
70
69 Expected A, E, F, H
71 Expected A, E, F, H
70 A
72 A
71 E
73 E
72 F
74 F
73 H
75 H
74
76
75 @ 7: H
77 @ 7: H
76 |
78 |
77 | o 6: G
79 | o 6: G
78 | |\
80 | |\
79 | | o 5: F
81 | | o 5: F
80 | | |
82 | | |
81 | | o 4: E
83 | | o 4: E
82 | | |
84 | | |
83 | o | 3: D
85 | o | 3: D
84 | |\|
86 | |\|
85 | o | 2: C
87 | o | 2: C
86 |/ /
88 |/ /
87 | o 1: B
89 | o 1: B
88 |/
90 |/
89 o 0: A
91 o 0: A
90
92
91
93
92 % Rebase and collapse - more than one external (fail)
94 % Rebase and collapse - more than one external (fail)
93 abort: unable to collapse, there is more than one external parent
95 abort: unable to collapse, there is more than one external parent
94
96
95 % Rebase and collapse - E onto H
97 % Rebase and collapse - E onto H
98 saved backup bundle to
96 adding branch
99 adding branch
97 adding changesets
100 adding changesets
98 adding manifests
101 adding manifests
99 adding file changes
102 adding file changes
100 added 2 changesets with 3 changes to 3 files
103 added 2 changesets with 3 changes to 3 files
101 rebase completed
104 rebase completed
102 @ 5: Collapsed revision
105 @ 5: Collapsed revision
103 |\ * E
106 |\ * E
104 | | * F
107 | | * F
105 | | * G
108 | | * G
106 | o 4: H
109 | o 4: H
107 | |
110 | |
108 o | 3: D
111 o | 3: D
109 |\ \
112 |\ \
110 | o | 2: C
113 | o | 2: C
111 | |/
114 | |/
112 o / 1: B
115 o / 1: B
113 |/
116 |/
114 o 0: A
117 o 0: A
115
118
116 Expected A, B, C, E, F, H
119 Expected A, B, C, E, F, H
117 A
120 A
118 B
121 B
119 C
122 C
120 E
123 E
121 F
124 F
122 H
125 H
123
126
124 @ 8: I
127 @ 8: I
125 |
128 |
126 | o 7: H
129 | o 7: H
127 | |\
130 | |\
128 | | o 6: G
131 | | o 6: G
129 | | |
132 | | |
130 | | o 5: F
133 | | o 5: F
131 | | |
134 | | |
132 | | o 4: E
135 | | o 4: E
133 | | |
136 | | |
134 | o | 3: D
137 | o | 3: D
135 | |\|
138 | |\|
136 | o | 2: C
139 | o | 2: C
137 |/ /
140 |/ /
138 | o 1: B
141 | o 1: B
139 |/
142 |/
140 o 0: A
143 o 0: A
141
144
142
145
143 % Rebase and collapse - E onto I
146 % Rebase and collapse - E onto I
144 merging E
147 merging E
148 saved backup bundle to
145 adding branch
149 adding branch
146 adding changesets
150 adding changesets
147 adding manifests
151 adding manifests
148 adding file changes
152 adding file changes
149 added 2 changesets with 3 changes to 3 files
153 added 2 changesets with 3 changes to 3 files
150 rebase completed
154 rebase completed
151 @ 5: Collapsed revision
155 @ 5: Collapsed revision
152 |\ * E
156 |\ * E
153 | | * F
157 | | * F
154 | | * G
158 | | * G
155 | | * H
159 | | * H
156 | o 4: I
160 | o 4: I
157 | |
161 | |
158 o | 3: D
162 o | 3: D
159 |\ \
163 |\ \
160 | o | 2: C
164 | o | 2: C
161 | |/
165 | |/
162 o / 1: B
166 o / 1: B
163 |/
167 |/
164 o 0: A
168 o 0: A
165
169
166 Expected A, B, C, E, G, I
170 Expected A, B, C, E, G, I
167 A
171 A
168 B
172 B
169 C
173 C
170 E
174 E
171 G
175 G
172 I
176 I
173 Cat E:
177 Cat E:
174 F
178 F
175
179
176 @ 5: F
180 @ 5: F
177 |
181 |
178 | o 4: E
182 | o 4: E
179 | |\
183 | |\
180 | | o 3: D
184 | | o 3: D
181 | | |
185 | | |
182 | o | 2: C
186 | o | 2: C
183 | |/
187 | |/
184 | o 1: B
188 | o 1: B
185 |/
189 |/
186 o 0: A
190 o 0: A
187
191
188
192
189 % Rebase and collapse - B onto F
193 % Rebase and collapse - B onto F
194 saved backup bundle to
190 adding branch
195 adding branch
191 adding changesets
196 adding changesets
192 adding manifests
197 adding manifests
193 adding file changes
198 adding file changes
194 added 2 changesets with 4 changes to 4 files
199 added 2 changesets with 4 changes to 4 files
195 rebase completed
200 rebase completed
196 @ 2: Collapsed revision
201 @ 2: Collapsed revision
197 | * B
202 | * B
198 | * C
203 | * C
199 | * D
204 | * D
200 | * E
205 | * E
201 o 1: F
206 o 1: F
202 |
207 |
203 o 0: A
208 o 0: A
204
209
205 Expected A, B, C, D, F
210 Expected A, B, C, D, F
206 A
211 A
207 B
212 B
208 C
213 C
209 D
214 D
210 F
215 F
@@ -1,65 +1,66 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 created new head
2 created new head
3 @ 5: L3
3 @ 5: L3
4 |
4 |
5 o 4: L2
5 o 4: L2
6 |
6 |
7 o 3: L1
7 o 3: L1
8 |
8 |
9 | o 2: C3
9 | o 2: C3
10 |/
10 |/
11 o 1: C2
11 o 1: C2
12 |
12 |
13 o 0: C1
13 o 0: C1
14
14
15
15
16 % Try to call --continue
16 % Try to call --continue
17 abort: no rebase in progress
17 abort: no rebase in progress
18
18
19 % Conflicting rebase
19 % Conflicting rebase
20 merging common
20 merging common
21 warning: conflicts during merge.
21 warning: conflicts during merge.
22 merging common failed!
22 merging common failed!
23 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
23 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
24
24
25 % Try to continue without solving the conflict
25 % Try to continue without solving the conflict
26 abort: unresolved merge conflicts (see hg resolve)
26 abort: unresolved merge conflicts (see hg resolve)
27
27
28 % Conclude rebase
28 % Conclude rebase
29 saved backup bundle to
29 adding branch
30 adding branch
30 adding changesets
31 adding changesets
31 adding manifests
32 adding manifests
32 adding file changes
33 adding file changes
33 added 3 changesets with 3 changes to 3 files
34 added 3 changesets with 3 changes to 3 files
34 rebase completed
35 rebase completed
35 @ 5: L3
36 @ 5: L3
36 |
37 |
37 o 4: L2
38 o 4: L2
38 |
39 |
39 o 3: L1
40 o 3: L1
40 |
41 |
41 o 2: C3
42 o 2: C3
42 |
43 |
43 o 1: C2
44 o 1: C2
44 |
45 |
45 o 0: C1
46 o 0: C1
46
47
47
48
48 % Check correctness
49 % Check correctness
49 - Rev. 0
50 - Rev. 0
50 c1
51 c1
51 - Rev. 1
52 - Rev. 1
52 c1
53 c1
53 c2
54 c2
54 - Rev. 2
55 - Rev. 2
55 c1
56 c1
56 c2
57 c2
57 c3
58 c3
58 - Rev. 3
59 - Rev. 3
59 c1
60 c1
60 c2
61 c2
61 c3
62 c3
62 - Rev. 4
63 - Rev. 4
63 resolved merge
64 resolved merge
64 - Rev. 5
65 - Rev. 5
65 resolved merge
66 resolved merge
@@ -1,130 +1,134 b''
1 @ 4: E
1 @ 4: E
2 |
2 |
3 | o 3: D
3 | o 3: D
4 | |
4 | |
5 | o 2: C
5 | o 2: C
6 | |
6 | |
7 | o 1: B
7 | o 1: B
8 |/
8 |/
9 o 0: A
9 o 0: A
10
10
11 % Rebasing D onto E detaching from C
11 % Rebasing D onto E detaching from C
12 saved backup bundle to
12 adding branch
13 adding branch
13 adding changesets
14 adding changesets
14 adding manifests
15 adding manifests
15 adding file changes
16 adding file changes
16 added 2 changesets with 2 changes to 2 files (+1 heads)
17 added 2 changesets with 2 changes to 2 files (+1 heads)
17 rebase completed
18 rebase completed
18 @ 4: D
19 @ 4: D
19 |
20 |
20 o 3: E
21 o 3: E
21 |
22 |
22 | o 2: C
23 | o 2: C
23 | |
24 | |
24 | o 1: B
25 | o 1: B
25 |/
26 |/
26 o 0: A
27 o 0: A
27
28
28 Expected A, D, E
29 Expected A, D, E
29 A
30 A
30 D
31 D
31 E
32 E
32
33
33 @ 4: E
34 @ 4: E
34 |
35 |
35 | o 3: D
36 | o 3: D
36 | |
37 | |
37 | o 2: C
38 | o 2: C
38 | |
39 | |
39 | o 1: B
40 | o 1: B
40 |/
41 |/
41 o 0: A
42 o 0: A
42
43
43 % Rebasing C onto E detaching from B
44 % Rebasing C onto E detaching from B
45 saved backup bundle to
44 adding branch
46 adding branch
45 adding changesets
47 adding changesets
46 adding manifests
48 adding manifests
47 adding file changes
49 adding file changes
48 added 3 changesets with 3 changes to 3 files (+1 heads)
50 added 3 changesets with 3 changes to 3 files (+1 heads)
49 rebase completed
51 rebase completed
50 @ 4: D
52 @ 4: D
51 |
53 |
52 o 3: C
54 o 3: C
53 |
55 |
54 o 2: E
56 o 2: E
55 |
57 |
56 | o 1: B
58 | o 1: B
57 |/
59 |/
58 o 0: A
60 o 0: A
59
61
60 Expected A, C, D, E
62 Expected A, C, D, E
61 A
63 A
62 C
64 C
63 D
65 D
64 E
66 E
65
67
66 @ 4: E
68 @ 4: E
67 |
69 |
68 | o 3: D
70 | o 3: D
69 | |
71 | |
70 | o 2: C
72 | o 2: C
71 | |
73 | |
72 | o 1: B
74 | o 1: B
73 |/
75 |/
74 o 0: A
76 o 0: A
75
77
76 % Rebasing B onto E using detach (same as not using it)
78 % Rebasing B onto E using detach (same as not using it)
79 saved backup bundle to
77 adding branch
80 adding branch
78 adding changesets
81 adding changesets
79 adding manifests
82 adding manifests
80 adding file changes
83 adding file changes
81 added 4 changesets with 4 changes to 4 files
84 added 4 changesets with 4 changes to 4 files
82 rebase completed
85 rebase completed
83 @ 4: D
86 @ 4: D
84 |
87 |
85 o 3: C
88 o 3: C
86 |
89 |
87 o 2: B
90 o 2: B
88 |
91 |
89 o 1: E
92 o 1: E
90 |
93 |
91 o 0: A
94 o 0: A
92
95
93 Expected A, B, C, D, E
96 Expected A, B, C, D, E
94 A
97 A
95 B
98 B
96 C
99 C
97 D
100 D
98 E
101 E
99
102
100 @ 4: E
103 @ 4: E
101 |
104 |
102 | o 3: D
105 | o 3: D
103 | |
106 | |
104 | o 2: C
107 | o 2: C
105 | |
108 | |
106 | o 1: B
109 | o 1: B
107 |/
110 |/
108 o 0: A
111 o 0: A
109
112
110 % Rebasing C onto E detaching from B and collapsing
113 % Rebasing C onto E detaching from B and collapsing
114 saved backup bundle to
111 adding branch
115 adding branch
112 adding changesets
116 adding changesets
113 adding manifests
117 adding manifests
114 adding file changes
118 adding file changes
115 added 2 changesets with 3 changes to 3 files (+1 heads)
119 added 2 changesets with 3 changes to 3 files (+1 heads)
116 rebase completed
120 rebase completed
117 @ 3: Collapsed revision
121 @ 3: Collapsed revision
118 | * C
122 | * C
119 | * D
123 | * D
120 o 2: E
124 o 2: E
121 |
125 |
122 | o 1: B
126 | o 1: B
123 |/
127 |/
124 o 0: A
128 o 0: A
125
129
126 Expected A, C, D, E
130 Expected A, C, D, E
127 A
131 A
128 C
132 C
129 D
133 D
130 E
134 E
@@ -1,62 +1,64 b''
1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2 created new head
2 created new head
3 @ 4:r2
3 @ 4:r2
4 |
4 |
5 o 3:r1
5 o 3:r1
6 |
6 |
7 | o 2:l1
7 | o 2:l1
8 |/
8 |/
9 o 1:c2
9 o 1:c2
10 |
10 |
11 o 0:c1
11 o 0:c1
12
12
13
13
14 % Rebase with no arguments - single revision in source branch
14 % Rebase with no arguments - single revision in source branch
15 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
16 saved backup bundle to
16 adding branch
17 adding branch
17 adding changesets
18 adding changesets
18 adding manifests
19 adding manifests
19 adding file changes
20 adding file changes
20 added 3 changesets with 3 changes to 3 files
21 added 3 changesets with 3 changes to 3 files
21 rebase completed
22 rebase completed
22 @ 4:l1
23 @ 4:l1
23 |
24 |
24 o 3:r2
25 o 3:r2
25 |
26 |
26 o 2:r1
27 o 2:r1
27 |
28 |
28 o 1:c2
29 o 1:c2
29 |
30 |
30 o 0:c1
31 o 0:c1
31
32
32 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
33 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
33 created new head
34 created new head
34 @ 4:r1
35 @ 4:r1
35 |
36 |
36 | o 3:l2
37 | o 3:l2
37 | |
38 | |
38 | o 2:l1
39 | o 2:l1
39 |/
40 |/
40 o 1:c2
41 o 1:c2
41 |
42 |
42 o 0:c1
43 o 0:c1
43
44
44
45
45 % Rebase with no arguments - single revision in target branch
46 % Rebase with no arguments - single revision in target branch
46 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
47 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
48 saved backup bundle to
47 adding branch
49 adding branch
48 adding changesets
50 adding changesets
49 adding manifests
51 adding manifests
50 adding file changes
52 adding file changes
51 added 3 changesets with 3 changes to 3 files
53 added 3 changesets with 3 changes to 3 files
52 rebase completed
54 rebase completed
53 @ 4:l2
55 @ 4:l2
54 |
56 |
55 o 3:l1
57 o 3:l1
56 |
58 |
57 o 2:r1
59 o 2:r1
58 |
60 |
59 o 1:c2
61 o 1:c2
60 |
62 |
61 o 0:c1
63 o 0:c1
62
64
@@ -1,22 +1,23 b''
1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2
2
3 % "Mainstream" import p1.patch
3 % "Mainstream" import p1.patch
4 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
4 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
5 applying p1.patch
5 applying p1.patch
6
6
7 % Rebase
7 % Rebase
8 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
8 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
9 saved backup bundle to
9 adding branch
10 adding branch
10 adding changesets
11 adding changesets
11 adding manifests
12 adding manifests
12 adding file changes
13 adding file changes
13 added 2 changesets with 2 changes to 2 files
14 added 2 changesets with 2 changes to 2 files
14 rebase completed
15 rebase completed
15 @ 3 P0 tags: p0.patch qbase qtip tip
16 @ 3 P0 tags: p0.patch qbase qtip tip
16 |
17 |
17 o 2 P1 tags: qparent
18 o 2 P1 tags: qparent
18 |
19 |
19 o 1 R1 tags:
20 o 1 R1 tags:
20 |
21 |
21 o 0 C1 tags:
22 o 0 C1 tags:
22
23
@@ -1,137 +1,138 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 @ 3 P1 tags: f2.patch qtip tip
2 @ 3 P1 tags: f2.patch qtip tip
3 |
3 |
4 o 2 P0 tags: f.patch qbase
4 o 2 P0 tags: f.patch qbase
5 |
5 |
6 | o 1 R1 tags:
6 | o 1 R1 tags:
7 |/
7 |/
8 o 0 C1 tags: qparent
8 o 0 C1 tags: qparent
9
9
10
10
11 % Rebase - try to rebase on an applied mq patch
11 % Rebase - try to rebase on an applied mq patch
12 abort: cannot rebase onto an applied mq patch
12 abort: cannot rebase onto an applied mq patch
13
13
14 % Rebase - same thing, but mq patch is default dest
14 % Rebase - same thing, but mq patch is default dest
15 abort: cannot rebase onto an applied mq patch
15 abort: cannot rebase onto an applied mq patch
16
16
17 % Rebase - generate a conflict
17 % Rebase - generate a conflict
18 merging f
18 merging f
19 warning: conflicts during merge.
19 warning: conflicts during merge.
20 merging f failed!
20 merging f failed!
21 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
21 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
22
22
23 % Fix the 1st conflict
23 % Fix the 1st conflict
24 warning: conflicts during merge.
24 warning: conflicts during merge.
25 merging f failed!
25 merging f failed!
26 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
26 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
27 merging f
27 merging f
28
28
29 % Fix the 2nd conflict
29 % Fix the 2nd conflict
30 saved backup bundle to
30 adding branch
31 adding branch
31 adding changesets
32 adding changesets
32 adding manifests
33 adding manifests
33 adding file changes
34 adding file changes
34 added 2 changesets with 2 changes to 1 files
35 added 2 changesets with 2 changes to 1 files
35 rebase completed
36 rebase completed
36 @ 3 P1 tags: f2.patch qtip tip
37 @ 3 P1 tags: f2.patch qtip tip
37 |
38 |
38 o 2 P0 tags: f.patch qbase
39 o 2 P0 tags: f.patch qbase
39 |
40 |
40 o 1 R1 tags: qparent
41 o 1 R1 tags: qparent
41 |
42 |
42 o 0 C1 tags:
43 o 0 C1 tags:
43
44
44
45
45 % Update to qbase
46 % Update to qbase
46 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 % f correctly reflects the merge result
48 % f correctly reflects the merge result
48 mq1r1
49 mq1r1
49 % And the patch is correct
50 % And the patch is correct
50 # HG changeset patch
51 # HG changeset patch
51 # User test
52 # User test
52 # Date
53 # Date
53 # Node ID
54 # Node ID
54 # Parent
55 # Parent
55 P0
56 P0
56
57
57 diff -r x -r y f
58 diff -r x -r y f
58 --- a/f
59 --- a/f
59 +++ b/f
60 +++ b/f
60 @@ -1,1 +1,1 @@
61 @@ -1,1 +1,1 @@
61 -r1
62 -r1
62 +mq1r1
63 +mq1r1
63
64
64 % Update to qtip
65 % Update to qtip
65 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 % f correctly reflects the merge result
67 % f correctly reflects the merge result
67 mq1r1mq2
68 mq1r1mq2
68 % And the patch is correct
69 % And the patch is correct
69 # HG changeset patch
70 # HG changeset patch
70 # User test
71 # User test
71 # Date
72 # Date
72 # Node ID
73 # Node ID
73 # Parent
74 # Parent
74 P1
75 P1
75
76
76 diff -r x -r y f
77 diff -r x -r y f
77 --- a/f
78 --- a/f
78 +++ b/f
79 +++ b/f
79 @@ -1,1 +1,1 @@
80 @@ -1,1 +1,1 @@
80 -mq1r1
81 -mq1r1
81 +mq1r1mq2
82 +mq1r1mq2
82
83
83 % Adding one git-style patch and one normal
84 % Adding one git-style patch and one normal
84 popping f2.patch
85 popping f2.patch
85 popping f.patch
86 popping f.patch
86 patch queue now empty
87 patch queue now empty
87 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 % Git patch
89 % Git patch
89 P0 (git)
90 P0 (git)
90
91
91 diff --git a/p b/p
92 diff --git a/p b/p
92 new file mode 100644
93 new file mode 100644
93 --- /dev/null
94 --- /dev/null
94 +++ b/p
95 +++ b/p
95 @@ -0,0 +1,1 @@
96 @@ -0,0 +1,1 @@
96 +mq1
97 +mq1
97
98
98 % Normal patch
99 % Normal patch
99 P1
100 P1
100
101
101 diff -r x p
102 diff -r x p
102 --- a/p
103 --- a/p
103 +++ b/p
104 +++ b/p
104 @@ -1,1 +1,1 @@
105 @@ -1,1 +1,1 @@
105 -mq1
106 -mq1
106 +mq2
107 +mq2
107
108
108 % Rebase the applied mq patches
109 % Rebase the applied mq patches
109 % And the patches are correct
110 % And the patches are correct
110 % Git patch
111 % Git patch
111 # HG changeset patch
112 # HG changeset patch
112 # User test
113 # User test
113 # Date
114 # Date
114 # Node ID
115 # Node ID
115 # Parent
116 # Parent
116 P0 (git)
117 P0 (git)
117
118
118 diff --git a/p b/p
119 diff --git a/p b/p
119 new file mode 100644
120 new file mode 100644
120 --- /dev/null
121 --- /dev/null
121 +++ b/p
122 +++ b/p
122 @@ -0,0 +1,1 @@
123 @@ -0,0 +1,1 @@
123 +mq1
124 +mq1
124
125
125 % Normal patch
126 % Normal patch
126 # HG changeset patch
127 # HG changeset patch
127 # User test
128 # User test
128 # Date
129 # Date
129 # Node ID
130 # Node ID
130 # Parent
131 # Parent
131 P1
132 P1
132
133
133 --- a/p
134 --- a/p
134 +++ b/p
135 +++ b/p
135 @@ -1,1 +1,1 @@
136 @@ -1,1 +1,1 @@
136 -mq1
137 -mq1
137 +mq2
138 +mq2
@@ -1,336 +1,344 b''
1 % These fail
1 % These fail
2
2
3 % Use continue and abort
3 % Use continue and abort
4 hg rebase: cannot use both abort and continue
4 hg rebase: cannot use both abort and continue
5 hg rebase [-s REV | -b REV] [-d REV] [options]
5 hg rebase [-s REV | -b REV] [-d REV] [options]
6 hg rebase {-a|-c}
6 hg rebase {-a|-c}
7
7
8 move changeset (and descendants) to a different branch
8 move changeset (and descendants) to a different branch
9
9
10 Rebase uses repeated merging to graft changesets from one part of history
10 Rebase uses repeated merging to graft changesets from one part of history
11 (the source) onto another (the destination). This can be useful for
11 (the source) onto another (the destination). This can be useful for
12 linearizing *local* changes relative to a master development tree.
12 linearizing *local* changes relative to a master development tree.
13
13
14 You should not rebase changesets that have already been shared with
14 You should not rebase changesets that have already been shared with
15 others. Doing so will force everybody else to perform the same rebase or
15 others. Doing so will force everybody else to perform the same rebase or
16 they will end up with duplicated changesets after pulling in your rebased
16 they will end up with duplicated changesets after pulling in your rebased
17 changesets.
17 changesets.
18
18
19 If you don't specify a destination changeset ("-d/--dest"), rebase uses
19 If you don't specify a destination changeset ("-d/--dest"), rebase uses
20 the tipmost head of the current named branch as the destination. (The
20 the tipmost head of the current named branch as the destination. (The
21 destination changeset is not modified by rebasing, but new changesets are
21 destination changeset is not modified by rebasing, but new changesets are
22 added as its descendants.)
22 added as its descendants.)
23
23
24 You can specify which changesets to rebase in two ways: as a "source"
24 You can specify which changesets to rebase in two ways: as a "source"
25 changeset or as a "base" changeset. Both are shorthand for a topologically
25 changeset or as a "base" changeset. Both are shorthand for a topologically
26 related set of changesets (the "source branch"). If you specify source
26 related set of changesets (the "source branch"). If you specify source
27 ("-s/--source"), rebase will rebase that changeset and all of its
27 ("-s/--source"), rebase will rebase that changeset and all of its
28 descendants onto dest. If you specify base ("-b/--base"), rebase will
28 descendants onto dest. If you specify base ("-b/--base"), rebase will
29 select ancestors of base back to but not including the common ancestor
29 select ancestors of base back to but not including the common ancestor
30 with dest. Thus, "-b" is less precise but more convenient than "-s": you
30 with dest. Thus, "-b" is less precise but more convenient than "-s": you
31 can specify any changeset in the source branch, and rebase will select the
31 can specify any changeset in the source branch, and rebase will select the
32 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
32 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
33 of the working directory as the base.
33 of the working directory as the base.
34
34
35 By default, rebase recreates the changesets in the source branch as
35 By default, rebase recreates the changesets in the source branch as
36 descendants of dest and then destroys the originals. Use "--keep" to
36 descendants of dest and then destroys the originals. Use "--keep" to
37 preserve the original source changesets. Some changesets in the source
37 preserve the original source changesets. Some changesets in the source
38 branch (e.g. merges from the destination branch) may be dropped if they no
38 branch (e.g. merges from the destination branch) may be dropped if they no
39 longer contribute any change.
39 longer contribute any change.
40
40
41 One result of the rules for selecting the destination changeset and source
41 One result of the rules for selecting the destination changeset and source
42 branch is that, unlike "merge", rebase will do nothing if you are at the
42 branch is that, unlike "merge", rebase will do nothing if you are at the
43 latest (tipmost) head of a named branch with two heads. You need to
43 latest (tipmost) head of a named branch with two heads. You need to
44 explicitly specify source and/or destination (or "update" to the other
44 explicitly specify source and/or destination (or "update" to the other
45 head, if it's the head of the intended source branch).
45 head, if it's the head of the intended source branch).
46
46
47 If a rebase is interrupted to manually resolve a merge, it can be
47 If a rebase is interrupted to manually resolve a merge, it can be
48 continued with --continue/-c or aborted with --abort/-a.
48 continued with --continue/-c or aborted with --abort/-a.
49
49
50 options:
50 options:
51
51
52 -s --source rebase from the specified changeset
52 -s --source rebase from the specified changeset
53 -b --base rebase from the base of the specified changeset (up to
53 -b --base rebase from the base of the specified changeset (up to
54 greatest common ancestor of base and dest)
54 greatest common ancestor of base and dest)
55 -d --dest rebase onto the specified changeset
55 -d --dest rebase onto the specified changeset
56 --collapse collapse the rebased changesets
56 --collapse collapse the rebased changesets
57 --keep keep original changesets
57 --keep keep original changesets
58 --keepbranches keep original branch names
58 --keepbranches keep original branch names
59 --detach force detaching of source from its original branch
59 --detach force detaching of source from its original branch
60 -c --continue continue an interrupted rebase
60 -c --continue continue an interrupted rebase
61 -a --abort abort an interrupted rebase
61 -a --abort abort an interrupted rebase
62 --style display using template map file
62 --style display using template map file
63 --template display with template
63 --template display with template
64
64
65 use "hg -v help rebase" to show global options
65 use "hg -v help rebase" to show global options
66
66
67 % Use continue and collapse
67 % Use continue and collapse
68 hg rebase: cannot use collapse with continue or abort
68 hg rebase: cannot use collapse with continue or abort
69 hg rebase [-s REV | -b REV] [-d REV] [options]
69 hg rebase [-s REV | -b REV] [-d REV] [options]
70 hg rebase {-a|-c}
70 hg rebase {-a|-c}
71
71
72 move changeset (and descendants) to a different branch
72 move changeset (and descendants) to a different branch
73
73
74 Rebase uses repeated merging to graft changesets from one part of history
74 Rebase uses repeated merging to graft changesets from one part of history
75 (the source) onto another (the destination). This can be useful for
75 (the source) onto another (the destination). This can be useful for
76 linearizing *local* changes relative to a master development tree.
76 linearizing *local* changes relative to a master development tree.
77
77
78 You should not rebase changesets that have already been shared with
78 You should not rebase changesets that have already been shared with
79 others. Doing so will force everybody else to perform the same rebase or
79 others. Doing so will force everybody else to perform the same rebase or
80 they will end up with duplicated changesets after pulling in your rebased
80 they will end up with duplicated changesets after pulling in your rebased
81 changesets.
81 changesets.
82
82
83 If you don't specify a destination changeset ("-d/--dest"), rebase uses
83 If you don't specify a destination changeset ("-d/--dest"), rebase uses
84 the tipmost head of the current named branch as the destination. (The
84 the tipmost head of the current named branch as the destination. (The
85 destination changeset is not modified by rebasing, but new changesets are
85 destination changeset is not modified by rebasing, but new changesets are
86 added as its descendants.)
86 added as its descendants.)
87
87
88 You can specify which changesets to rebase in two ways: as a "source"
88 You can specify which changesets to rebase in two ways: as a "source"
89 changeset or as a "base" changeset. Both are shorthand for a topologically
89 changeset or as a "base" changeset. Both are shorthand for a topologically
90 related set of changesets (the "source branch"). If you specify source
90 related set of changesets (the "source branch"). If you specify source
91 ("-s/--source"), rebase will rebase that changeset and all of its
91 ("-s/--source"), rebase will rebase that changeset and all of its
92 descendants onto dest. If you specify base ("-b/--base"), rebase will
92 descendants onto dest. If you specify base ("-b/--base"), rebase will
93 select ancestors of base back to but not including the common ancestor
93 select ancestors of base back to but not including the common ancestor
94 with dest. Thus, "-b" is less precise but more convenient than "-s": you
94 with dest. Thus, "-b" is less precise but more convenient than "-s": you
95 can specify any changeset in the source branch, and rebase will select the
95 can specify any changeset in the source branch, and rebase will select the
96 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
96 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
97 of the working directory as the base.
97 of the working directory as the base.
98
98
99 By default, rebase recreates the changesets in the source branch as
99 By default, rebase recreates the changesets in the source branch as
100 descendants of dest and then destroys the originals. Use "--keep" to
100 descendants of dest and then destroys the originals. Use "--keep" to
101 preserve the original source changesets. Some changesets in the source
101 preserve the original source changesets. Some changesets in the source
102 branch (e.g. merges from the destination branch) may be dropped if they no
102 branch (e.g. merges from the destination branch) may be dropped if they no
103 longer contribute any change.
103 longer contribute any change.
104
104
105 One result of the rules for selecting the destination changeset and source
105 One result of the rules for selecting the destination changeset and source
106 branch is that, unlike "merge", rebase will do nothing if you are at the
106 branch is that, unlike "merge", rebase will do nothing if you are at the
107 latest (tipmost) head of a named branch with two heads. You need to
107 latest (tipmost) head of a named branch with two heads. You need to
108 explicitly specify source and/or destination (or "update" to the other
108 explicitly specify source and/or destination (or "update" to the other
109 head, if it's the head of the intended source branch).
109 head, if it's the head of the intended source branch).
110
110
111 If a rebase is interrupted to manually resolve a merge, it can be
111 If a rebase is interrupted to manually resolve a merge, it can be
112 continued with --continue/-c or aborted with --abort/-a.
112 continued with --continue/-c or aborted with --abort/-a.
113
113
114 options:
114 options:
115
115
116 -s --source rebase from the specified changeset
116 -s --source rebase from the specified changeset
117 -b --base rebase from the base of the specified changeset (up to
117 -b --base rebase from the base of the specified changeset (up to
118 greatest common ancestor of base and dest)
118 greatest common ancestor of base and dest)
119 -d --dest rebase onto the specified changeset
119 -d --dest rebase onto the specified changeset
120 --collapse collapse the rebased changesets
120 --collapse collapse the rebased changesets
121 --keep keep original changesets
121 --keep keep original changesets
122 --keepbranches keep original branch names
122 --keepbranches keep original branch names
123 --detach force detaching of source from its original branch
123 --detach force detaching of source from its original branch
124 -c --continue continue an interrupted rebase
124 -c --continue continue an interrupted rebase
125 -a --abort abort an interrupted rebase
125 -a --abort abort an interrupted rebase
126 --style display using template map file
126 --style display using template map file
127 --template display with template
127 --template display with template
128
128
129 use "hg -v help rebase" to show global options
129 use "hg -v help rebase" to show global options
130
130
131 % Use continue/abort and dest/source
131 % Use continue/abort and dest/source
132 hg rebase: abort and continue do not allow specifying revisions
132 hg rebase: abort and continue do not allow specifying revisions
133 hg rebase [-s REV | -b REV] [-d REV] [options]
133 hg rebase [-s REV | -b REV] [-d REV] [options]
134 hg rebase {-a|-c}
134 hg rebase {-a|-c}
135
135
136 move changeset (and descendants) to a different branch
136 move changeset (and descendants) to a different branch
137
137
138 Rebase uses repeated merging to graft changesets from one part of history
138 Rebase uses repeated merging to graft changesets from one part of history
139 (the source) onto another (the destination). This can be useful for
139 (the source) onto another (the destination). This can be useful for
140 linearizing *local* changes relative to a master development tree.
140 linearizing *local* changes relative to a master development tree.
141
141
142 You should not rebase changesets that have already been shared with
142 You should not rebase changesets that have already been shared with
143 others. Doing so will force everybody else to perform the same rebase or
143 others. Doing so will force everybody else to perform the same rebase or
144 they will end up with duplicated changesets after pulling in your rebased
144 they will end up with duplicated changesets after pulling in your rebased
145 changesets.
145 changesets.
146
146
147 If you don't specify a destination changeset ("-d/--dest"), rebase uses
147 If you don't specify a destination changeset ("-d/--dest"), rebase uses
148 the tipmost head of the current named branch as the destination. (The
148 the tipmost head of the current named branch as the destination. (The
149 destination changeset is not modified by rebasing, but new changesets are
149 destination changeset is not modified by rebasing, but new changesets are
150 added as its descendants.)
150 added as its descendants.)
151
151
152 You can specify which changesets to rebase in two ways: as a "source"
152 You can specify which changesets to rebase in two ways: as a "source"
153 changeset or as a "base" changeset. Both are shorthand for a topologically
153 changeset or as a "base" changeset. Both are shorthand for a topologically
154 related set of changesets (the "source branch"). If you specify source
154 related set of changesets (the "source branch"). If you specify source
155 ("-s/--source"), rebase will rebase that changeset and all of its
155 ("-s/--source"), rebase will rebase that changeset and all of its
156 descendants onto dest. If you specify base ("-b/--base"), rebase will
156 descendants onto dest. If you specify base ("-b/--base"), rebase will
157 select ancestors of base back to but not including the common ancestor
157 select ancestors of base back to but not including the common ancestor
158 with dest. Thus, "-b" is less precise but more convenient than "-s": you
158 with dest. Thus, "-b" is less precise but more convenient than "-s": you
159 can specify any changeset in the source branch, and rebase will select the
159 can specify any changeset in the source branch, and rebase will select the
160 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
160 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
161 of the working directory as the base.
161 of the working directory as the base.
162
162
163 By default, rebase recreates the changesets in the source branch as
163 By default, rebase recreates the changesets in the source branch as
164 descendants of dest and then destroys the originals. Use "--keep" to
164 descendants of dest and then destroys the originals. Use "--keep" to
165 preserve the original source changesets. Some changesets in the source
165 preserve the original source changesets. Some changesets in the source
166 branch (e.g. merges from the destination branch) may be dropped if they no
166 branch (e.g. merges from the destination branch) may be dropped if they no
167 longer contribute any change.
167 longer contribute any change.
168
168
169 One result of the rules for selecting the destination changeset and source
169 One result of the rules for selecting the destination changeset and source
170 branch is that, unlike "merge", rebase will do nothing if you are at the
170 branch is that, unlike "merge", rebase will do nothing if you are at the
171 latest (tipmost) head of a named branch with two heads. You need to
171 latest (tipmost) head of a named branch with two heads. You need to
172 explicitly specify source and/or destination (or "update" to the other
172 explicitly specify source and/or destination (or "update" to the other
173 head, if it's the head of the intended source branch).
173 head, if it's the head of the intended source branch).
174
174
175 If a rebase is interrupted to manually resolve a merge, it can be
175 If a rebase is interrupted to manually resolve a merge, it can be
176 continued with --continue/-c or aborted with --abort/-a.
176 continued with --continue/-c or aborted with --abort/-a.
177
177
178 options:
178 options:
179
179
180 -s --source rebase from the specified changeset
180 -s --source rebase from the specified changeset
181 -b --base rebase from the base of the specified changeset (up to
181 -b --base rebase from the base of the specified changeset (up to
182 greatest common ancestor of base and dest)
182 greatest common ancestor of base and dest)
183 -d --dest rebase onto the specified changeset
183 -d --dest rebase onto the specified changeset
184 --collapse collapse the rebased changesets
184 --collapse collapse the rebased changesets
185 --keep keep original changesets
185 --keep keep original changesets
186 --keepbranches keep original branch names
186 --keepbranches keep original branch names
187 --detach force detaching of source from its original branch
187 --detach force detaching of source from its original branch
188 -c --continue continue an interrupted rebase
188 -c --continue continue an interrupted rebase
189 -a --abort abort an interrupted rebase
189 -a --abort abort an interrupted rebase
190 --style display using template map file
190 --style display using template map file
191 --template display with template
191 --template display with template
192
192
193 use "hg -v help rebase" to show global options
193 use "hg -v help rebase" to show global options
194
194
195 % Use source and base
195 % Use source and base
196 hg rebase: cannot specify both a revision and a base
196 hg rebase: cannot specify both a revision and a base
197 hg rebase [-s REV | -b REV] [-d REV] [options]
197 hg rebase [-s REV | -b REV] [-d REV] [options]
198 hg rebase {-a|-c}
198 hg rebase {-a|-c}
199
199
200 move changeset (and descendants) to a different branch
200 move changeset (and descendants) to a different branch
201
201
202 Rebase uses repeated merging to graft changesets from one part of history
202 Rebase uses repeated merging to graft changesets from one part of history
203 (the source) onto another (the destination). This can be useful for
203 (the source) onto another (the destination). This can be useful for
204 linearizing *local* changes relative to a master development tree.
204 linearizing *local* changes relative to a master development tree.
205
205
206 You should not rebase changesets that have already been shared with
206 You should not rebase changesets that have already been shared with
207 others. Doing so will force everybody else to perform the same rebase or
207 others. Doing so will force everybody else to perform the same rebase or
208 they will end up with duplicated changesets after pulling in your rebased
208 they will end up with duplicated changesets after pulling in your rebased
209 changesets.
209 changesets.
210
210
211 If you don't specify a destination changeset ("-d/--dest"), rebase uses
211 If you don't specify a destination changeset ("-d/--dest"), rebase uses
212 the tipmost head of the current named branch as the destination. (The
212 the tipmost head of the current named branch as the destination. (The
213 destination changeset is not modified by rebasing, but new changesets are
213 destination changeset is not modified by rebasing, but new changesets are
214 added as its descendants.)
214 added as its descendants.)
215
215
216 You can specify which changesets to rebase in two ways: as a "source"
216 You can specify which changesets to rebase in two ways: as a "source"
217 changeset or as a "base" changeset. Both are shorthand for a topologically
217 changeset or as a "base" changeset. Both are shorthand for a topologically
218 related set of changesets (the "source branch"). If you specify source
218 related set of changesets (the "source branch"). If you specify source
219 ("-s/--source"), rebase will rebase that changeset and all of its
219 ("-s/--source"), rebase will rebase that changeset and all of its
220 descendants onto dest. If you specify base ("-b/--base"), rebase will
220 descendants onto dest. If you specify base ("-b/--base"), rebase will
221 select ancestors of base back to but not including the common ancestor
221 select ancestors of base back to but not including the common ancestor
222 with dest. Thus, "-b" is less precise but more convenient than "-s": you
222 with dest. Thus, "-b" is less precise but more convenient than "-s": you
223 can specify any changeset in the source branch, and rebase will select the
223 can specify any changeset in the source branch, and rebase will select the
224 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
224 whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
225 of the working directory as the base.
225 of the working directory as the base.
226
226
227 By default, rebase recreates the changesets in the source branch as
227 By default, rebase recreates the changesets in the source branch as
228 descendants of dest and then destroys the originals. Use "--keep" to
228 descendants of dest and then destroys the originals. Use "--keep" to
229 preserve the original source changesets. Some changesets in the source
229 preserve the original source changesets. Some changesets in the source
230 branch (e.g. merges from the destination branch) may be dropped if they no
230 branch (e.g. merges from the destination branch) may be dropped if they no
231 longer contribute any change.
231 longer contribute any change.
232
232
233 One result of the rules for selecting the destination changeset and source
233 One result of the rules for selecting the destination changeset and source
234 branch is that, unlike "merge", rebase will do nothing if you are at the
234 branch is that, unlike "merge", rebase will do nothing if you are at the
235 latest (tipmost) head of a named branch with two heads. You need to
235 latest (tipmost) head of a named branch with two heads. You need to
236 explicitly specify source and/or destination (or "update" to the other
236 explicitly specify source and/or destination (or "update" to the other
237 head, if it's the head of the intended source branch).
237 head, if it's the head of the intended source branch).
238
238
239 If a rebase is interrupted to manually resolve a merge, it can be
239 If a rebase is interrupted to manually resolve a merge, it can be
240 continued with --continue/-c or aborted with --abort/-a.
240 continued with --continue/-c or aborted with --abort/-a.
241
241
242 options:
242 options:
243
243
244 -s --source rebase from the specified changeset
244 -s --source rebase from the specified changeset
245 -b --base rebase from the base of the specified changeset (up to
245 -b --base rebase from the base of the specified changeset (up to
246 greatest common ancestor of base and dest)
246 greatest common ancestor of base and dest)
247 -d --dest rebase onto the specified changeset
247 -d --dest rebase onto the specified changeset
248 --collapse collapse the rebased changesets
248 --collapse collapse the rebased changesets
249 --keep keep original changesets
249 --keep keep original changesets
250 --keepbranches keep original branch names
250 --keepbranches keep original branch names
251 --detach force detaching of source from its original branch
251 --detach force detaching of source from its original branch
252 -c --continue continue an interrupted rebase
252 -c --continue continue an interrupted rebase
253 -a --abort abort an interrupted rebase
253 -a --abort abort an interrupted rebase
254 --style display using template map file
254 --style display using template map file
255 --template display with template
255 --template display with template
256
256
257 use "hg -v help rebase" to show global options
257 use "hg -v help rebase" to show global options
258
258
259 % Rebase with no arguments - from current
259 % Rebase with no arguments - from current
260 nothing to rebase
260 nothing to rebase
261
261
262 % Rebase with no arguments - from the current branch
262 % Rebase with no arguments - from the current branch
263 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
263 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
264 nothing to rebase
264 nothing to rebase
265 % ----------
265 % ----------
266 % These work
266 % These work
267
267
268 % Rebase with no arguments (from 3 onto 7)
268 % Rebase with no arguments (from 3 onto 7)
269 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
269 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
270 saved backup bundle to
270 adding branch
271 adding branch
271 adding changesets
272 adding changesets
272 adding manifests
273 adding manifests
273 adding file changes
274 adding file changes
274 added 5 changesets with 5 changes to 5 files
275 added 5 changesets with 5 changes to 5 files
275 rebase completed
276 rebase completed
276 % Try to rollback after a rebase (fail)
277 % Try to rollback after a rebase (fail)
277 no rollback information available
278 no rollback information available
278
279
279 % Rebase with base == '.' => same as no arguments (from 3 onto 7)
280 % Rebase with base == '.' => same as no arguments (from 3 onto 7)
280 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
281 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
282 saved backup bundle to
281 adding branch
283 adding branch
282 adding changesets
284 adding changesets
283 adding manifests
285 adding manifests
284 adding file changes
286 adding file changes
285 added 5 changesets with 5 changes to 5 files
287 added 5 changesets with 5 changes to 5 files
286 rebase completed
288 rebase completed
287
289
288 % Rebase with dest == default => same as no arguments (from 3 onto 7)
290 % Rebase with dest == default => same as no arguments (from 3 onto 7)
289 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
291 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
292 saved backup bundle to
290 adding branch
293 adding branch
291 adding changesets
294 adding changesets
292 adding manifests
295 adding manifests
293 adding file changes
296 adding file changes
294 added 5 changesets with 5 changes to 5 files
297 added 5 changesets with 5 changes to 5 files
295 rebase completed
298 rebase completed
296
299
297 % Specify only source (from 4 onto 7)
300 % Specify only source (from 4 onto 7)
301 saved backup bundle to
298 adding branch
302 adding branch
299 adding changesets
303 adding changesets
300 adding manifests
304 adding manifests
301 adding file changes
305 adding file changes
302 added 4 changesets with 4 changes to 4 files (-1 heads)
306 added 4 changesets with 4 changes to 4 files (-1 heads)
303 rebase completed
307 rebase completed
304
308
305 % Specify only dest (from 3 onto 6)
309 % Specify only dest (from 3 onto 6)
306 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
310 3 files updated, 0 files merged, 3 files removed, 0 files unresolved
311 saved backup bundle to
307 adding branch
312 adding branch
308 adding changesets
313 adding changesets
309 adding manifests
314 adding manifests
310 adding file changes
315 adding file changes
311 added 5 changesets with 5 changes to 5 files (+1 heads)
316 added 5 changesets with 5 changes to 5 files (+1 heads)
312 rebase completed
317 rebase completed
313
318
314 % Specify only base (from 3 onto 7)
319 % Specify only base (from 3 onto 7)
320 saved backup bundle to
315 adding branch
321 adding branch
316 adding changesets
322 adding changesets
317 adding manifests
323 adding manifests
318 adding file changes
324 adding file changes
319 added 5 changesets with 5 changes to 5 files
325 added 5 changesets with 5 changes to 5 files
320 rebase completed
326 rebase completed
321
327
322 % Specify source and dest (from 4 onto 6)
328 % Specify source and dest (from 4 onto 6)
329 saved backup bundle to
323 adding branch
330 adding branch
324 adding changesets
331 adding changesets
325 adding manifests
332 adding manifests
326 adding file changes
333 adding file changes
327 added 4 changesets with 4 changes to 4 files
334 added 4 changesets with 4 changes to 4 files
328 rebase completed
335 rebase completed
329
336
330 % Specify base and dest (from 3 onto 6)
337 % Specify base and dest (from 3 onto 6)
338 saved backup bundle to
331 adding branch
339 adding branch
332 adding changesets
340 adding changesets
333 adding manifests
341 adding manifests
334 adding file changes
342 adding file changes
335 added 5 changesets with 5 changes to 5 files (+1 heads)
343 added 5 changesets with 5 changes to 5 files (+1 heads)
336 rebase completed
344 rebase completed
@@ -1,56 +1,57 b''
1 updating to branch default
1 updating to branch default
2 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 updating to branch default
3 updating to branch default
4 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
5
5
6 % Now b has one revision to be pulled from a
6 % Now b has one revision to be pulled from a
7 pulling from
7 pulling from
8 searching for changes
8 searching for changes
9 adding changesets
9 adding changesets
10 adding manifests
10 adding manifests
11 adding file changes
11 adding file changes
12 added 1 changesets with 1 changes to 1 files (+1 heads)
12 added 1 changesets with 1 changes to 1 files (+1 heads)
13 saved backup bundle to
13 adding branch
14 adding branch
14 adding changesets
15 adding changesets
15 adding manifests
16 adding manifests
16 adding file changes
17 adding file changes
17 added 2 changesets with 2 changes to 2 files
18 added 2 changesets with 2 changes to 2 files
18 rebase completed
19 rebase completed
19 @ 3:L1
20 @ 3:L1
20 |
21 |
21 o 2:R1
22 o 2:R1
22 |
23 |
23 o 1:C2
24 o 1:C2
24 |
25 |
25 o 0:C1
26 o 0:C1
26
27
27
28
28 % Re-run pull --rebase
29 % Re-run pull --rebase
29 pulling from
30 pulling from
30 searching for changes
31 searching for changes
31 no changes found
32 no changes found
32
33
33 % Invoke pull --rebase and nothing to rebase
34 % Invoke pull --rebase and nothing to rebase
34 pulling from
35 pulling from
35 searching for changes
36 searching for changes
36 adding changesets
37 adding changesets
37 adding manifests
38 adding manifests
38 adding file changes
39 adding file changes
39 added 1 changesets with 1 changes to 1 files
40 added 1 changesets with 1 changes to 1 files
40 nothing to rebase
41 nothing to rebase
41 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 @ 2
43 @ 2
43 |
44 |
44
45
45 % pull --rebase --update should ignore --update
46 % pull --rebase --update should ignore --update
46 pulling from
47 pulling from
47 searching for changes
48 searching for changes
48 no changes found
49 no changes found
49
50
50 % pull --rebase doesn't update if nothing has been pulled
51 % pull --rebase doesn't update if nothing has been pulled
51 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 pulling from
53 pulling from
53 searching for changes
54 searching for changes
54 no changes found
55 no changes found
55 o 2
56 o 2
56 |
57 |
@@ -1,138 +1,144 b''
1 @ 5: F
1 @ 5: F
2 |
2 |
3 | o 4: E
3 | o 4: E
4 |/|
4 |/|
5 o | 3: D
5 o | 3: D
6 | |
6 | |
7 | o 2: C
7 | o 2: C
8 |/
8 |/
9 | o 1: B
9 | o 1: B
10 |/
10 |/
11 o 0: A
11 o 0: A
12
12
13 % Rebasing
13 % Rebasing
14 % B onto F - simple rebase
14 % B onto F - simple rebase
15 saved backup bundle to
15 adding branch
16 adding branch
16 adding changesets
17 adding changesets
17 adding manifests
18 adding manifests
18 adding file changes
19 adding file changes
19 added 5 changesets with 4 changes to 4 files (+1 heads)
20 added 5 changesets with 4 changes to 4 files (+1 heads)
20 rebase completed
21 rebase completed
21 @ 5: B
22 @ 5: B
22 |
23 |
23 o 4: F
24 o 4: F
24 |
25 |
25 | o 3: E
26 | o 3: E
26 |/|
27 |/|
27 o | 2: D
28 o | 2: D
28 | |
29 | |
29 | o 1: C
30 | o 1: C
30 |/
31 |/
31 o 0: A
32 o 0: A
32
33
33 % B onto D - intermediate point
34 % B onto D - intermediate point
35 saved backup bundle to
34 adding branch
36 adding branch
35 adding changesets
37 adding changesets
36 adding manifests
38 adding manifests
37 adding file changes
39 adding file changes
38 added 5 changesets with 4 changes to 4 files (+2 heads)
40 added 5 changesets with 4 changes to 4 files (+2 heads)
39 rebase completed
41 rebase completed
40 @ 5: B
42 @ 5: B
41 |
43 |
42 | o 4: F
44 | o 4: F
43 |/
45 |/
44 | o 3: E
46 | o 3: E
45 |/|
47 |/|
46 o | 2: D
48 o | 2: D
47 | |
49 | |
48 | o 1: C
50 | o 1: C
49 |/
51 |/
50 o 0: A
52 o 0: A
51
53
52 % C onto F - skip of E
54 % C onto F - skip of E
55 saved backup bundle to
53 adding branch
56 adding branch
54 adding changesets
57 adding changesets
55 adding manifests
58 adding manifests
56 adding file changes
59 adding file changes
57 added 3 changesets with 3 changes to 3 files (+1 heads)
60 added 3 changesets with 3 changes to 3 files (+1 heads)
58 rebase completed
61 rebase completed
59 @ 4: C
62 @ 4: C
60 |
63 |
61 o 3: F
64 o 3: F
62 |
65 |
63 o 2: D
66 o 2: D
64 |
67 |
65 | o 1: B
68 | o 1: B
66 |/
69 |/
67 o 0: A
70 o 0: A
68
71
69 % D onto C - rebase of a branching point (skip E)
72 % D onto C - rebase of a branching point (skip E)
73 saved backup bundle to
70 adding branch
74 adding branch
71 adding changesets
75 adding changesets
72 adding manifests
76 adding manifests
73 adding file changes
77 adding file changes
74 added 2 changesets with 2 changes to 2 files
78 added 2 changesets with 2 changes to 2 files
75 rebase completed
79 rebase completed
76 @ 4: F
80 @ 4: F
77 |
81 |
78 o 3: D
82 o 3: D
79 |
83 |
80 o 2: C
84 o 2: C
81 |
85 |
82 | o 1: B
86 | o 1: B
83 |/
87 |/
84 o 0: A
88 o 0: A
85
89
86 % E onto F - merged revision having a parent in ancestors of target
90 % E onto F - merged revision having a parent in ancestors of target
91 saved backup bundle to
87 adding branch
92 adding branch
88 adding changesets
93 adding changesets
89 adding manifests
94 adding manifests
90 adding file changes
95 adding file changes
91 added 2 changesets with 1 changes to 1 files (-1 heads)
96 added 2 changesets with 1 changes to 1 files (-1 heads)
92 rebase completed
97 rebase completed
93 @ 5: E
98 @ 5: E
94 |\
99 |\
95 | o 4: F
100 | o 4: F
96 | |
101 | |
97 | o 3: D
102 | o 3: D
98 | |
103 | |
99 o | 2: C
104 o | 2: C
100 |/
105 |/
101 | o 1: B
106 | o 1: B
102 |/
107 |/
103 o 0: A
108 o 0: A
104
109
105 % D onto B - E maintains C as parent
110 % D onto B - E maintains C as parent
111 saved backup bundle to
106 adding branch
112 adding branch
107 adding changesets
113 adding changesets
108 adding manifests
114 adding manifests
109 adding file changes
115 adding file changes
110 added 3 changesets with 2 changes to 2 files
116 added 3 changesets with 2 changes to 2 files
111 rebase completed
117 rebase completed
112 @ 5: F
118 @ 5: F
113 |
119 |
114 | o 4: E
120 | o 4: E
115 |/|
121 |/|
116 o | 3: D
122 o | 3: D
117 | |
123 | |
118 | o 2: C
124 | o 2: C
119 | |
125 | |
120 o | 1: B
126 o | 1: B
121 |/
127 |/
122 o 0: A
128 o 0: A
123
129
124 % These will fail (using --source)
130 % These will fail (using --source)
125 % E onto D - rebase onto an ancestor
131 % E onto D - rebase onto an ancestor
126 abort: source is descendant of destination
132 abort: source is descendant of destination
127 % D onto E - rebase onto a descendant
133 % D onto E - rebase onto a descendant
128 abort: source is ancestor of destination
134 abort: source is ancestor of destination
129 % E onto B - merge revision with both parents not in ancestors of target
135 % E onto B - merge revision with both parents not in ancestors of target
130 abort: cannot use revision 4 as base, result would have 3 parents
136 abort: cannot use revision 4 as base, result would have 3 parents
131
137
132 % These will abort gracefully (using --base)
138 % These will abort gracefully (using --base)
133 % E onto E - rebase onto same changeset
139 % E onto E - rebase onto same changeset
134 nothing to rebase
140 nothing to rebase
135 % E onto D - rebase onto an ancestor
141 % E onto D - rebase onto an ancestor
136 nothing to rebase
142 nothing to rebase
137 % D onto E - rebase onto a descendant
143 % D onto E - rebase onto a descendant
138 nothing to rebase
144 nothing to rebase
General Comments 0
You need to be logged in to leave comments. Login now