Show More
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
@@ -15,7 +15,7 b' http://mercurial.selenic.com/wiki/Rebase' | |||||
15 | ''' |
|
15 | ''' | |
16 |
|
16 | |||
17 | from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks |
|
17 | from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks | |
18 | from mercurial import extensions, patch |
|
18 | from mercurial import extensions, patch, scmutil | |
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 | |
@@ -34,6 +34,9 b' command = cmdutil.command(cmdtable)' | |||||
34 | _('rebase from the base of the specified changeset ' |
|
34 | _('rebase from the base of the specified changeset ' | |
35 | '(up to greatest common ancestor of base and dest)'), |
|
35 | '(up to greatest common ancestor of base and dest)'), | |
36 | _('REV')), |
|
36 | _('REV')), | |
|
37 | ('r', 'rev', [], | |||
|
38 | _('rebase these revisions'), | |||
|
39 | _('REV')), | |||
37 | ('d', 'dest', '', |
|
40 | ('d', 'dest', '', | |
38 | _('rebase onto the specified changeset'), _('REV')), |
|
41 | _('rebase onto the specified changeset'), _('REV')), | |
39 | ('', 'collapse', False, _('collapse the rebased changesets')), |
|
42 | ('', 'collapse', False, _('collapse the rebased changesets')), | |
@@ -119,6 +122,7 b' def rebase(ui, repo, **opts):' | |||||
119 | destf = opts.get('dest', None) |
|
122 | destf = opts.get('dest', None) | |
120 | srcf = opts.get('source', None) |
|
123 | srcf = opts.get('source', None) | |
121 | basef = opts.get('base', None) |
|
124 | basef = opts.get('base', None) | |
|
125 | revf = opts.get('rev', []) | |||
122 | contf = opts.get('continue') |
|
126 | contf = opts.get('continue') | |
123 | abortf = opts.get('abort') |
|
127 | abortf = opts.get('abort') | |
124 | collapsef = opts.get('collapse', False) |
|
128 | collapsef = opts.get('collapse', False) | |
@@ -156,7 +160,13 b' def rebase(ui, repo, **opts):' | |||||
156 | else: |
|
160 | else: | |
157 | if srcf and basef: |
|
161 | if srcf and basef: | |
158 | raise util.Abort(_('cannot specify both a ' |
|
162 | raise util.Abort(_('cannot specify both a ' | |
|
163 | 'source and a base')) | |||
|
164 | if revf and basef: | |||
|
165 | raise util.Abort(_('cannot specify both a' | |||
159 | 'revision and a base')) |
|
166 | 'revision and a base')) | |
|
167 | if revf and srcf: | |||
|
168 | raise util.Abort(_('cannot specify both a' | |||
|
169 | 'revision and a source')) | |||
160 | if detachf: |
|
170 | if detachf: | |
161 | if not srcf: |
|
171 | if not srcf: | |
162 | raise util.Abort( |
|
172 | raise util.Abort( | |
@@ -167,24 +177,39 b' def rebase(ui, repo, **opts):' | |||||
167 | cmdutil.bailifchanged(repo) |
|
177 | cmdutil.bailifchanged(repo) | |
168 |
|
178 | |||
169 | if not destf: |
|
179 | if not destf: | |
170 |
# Destination defaults to the latest revision in the |
|
180 | # Destination defaults to the latest revision in the | |
|
181 | # current branch | |||
171 | branch = repo[None].branch() |
|
182 | branch = repo[None].branch() | |
172 | dest = repo[branch] |
|
183 | dest = repo[branch] | |
173 | else: |
|
184 | else: | |
174 | dest = repo[destf] |
|
185 | dest = repo[destf] | |
175 |
|
186 | |||
|
187 | rebaseset = None | |||
176 | if srcf: |
|
188 | if srcf: | |
177 | revsetargs = ('(%r)::', srcf) |
|
189 | revsetargs = ('(%r)::', srcf) | |
|
190 | elif revf: | |||
|
191 | rebaseset = scmutil.revrange(repo, revf) | |||
|
192 | if not keepf and rebaseset: | |||
|
193 | try: | |||
|
194 | repo.set('children(%ld) - %ld', | |||
|
195 | rebaseset, rebaseset).next() | |||
|
196 | except StopIteration: | |||
|
197 | pass # empty revset is what we look for | |||
|
198 | else: | |||
|
199 | msg = _("can't remove original changesets with" | |||
|
200 | " unrebased descendants") | |||
|
201 | hint = _('use --keep to keep original changesets') | |||
|
202 | raise util.Abort(msg, hint=hint) | |||
178 | else: |
|
203 | else: | |
179 | base = basef or '.' |
|
204 | base = basef or '.' | |
180 | revsetargs = ('(children(ancestor(%r, %d)) and ::(%r))::', |
|
205 | revsetargs = ('(children(ancestor(%r, %d)) and ::(%r))::', | |
181 | base, dest, base) |
|
206 | base, dest, base) | |
182 |
|
207 | if rebaseset is None: | ||
183 | rebaseset = [c.rev() for c in repo.set(*revsetargs)] |
|
208 | rebaseset = [c.rev() for c in repo.set(*revsetargs)] | |
184 | if rebaseset: |
|
209 | if rebaseset: | |
185 | result = buildstate(repo, dest, rebaseset, detachf) |
|
210 | result = buildstate(repo, dest, rebaseset, detachf) | |
186 | else: |
|
211 | else: | |
187 |
repo.ui.debug( |
|
212 | repo.ui.debug('base is ancestor of destination') | |
188 | result = None |
|
213 | result = None | |
189 | if not result: |
|
214 | if not result: | |
190 | # Empty state built, nothing to rebase |
|
215 | # Empty state built, nothing to rebase | |
@@ -545,9 +570,9 b' def buildstate(repo, dest, rebaseset, de' | |||||
545 | detachset = set() |
|
570 | detachset = set() | |
546 | roots = list(repo.set('roots(%ld)', rebaseset)) |
|
571 | roots = list(repo.set('roots(%ld)', rebaseset)) | |
547 | if not roots: |
|
572 | if not roots: | |
548 |
raise util.Abort( |
|
573 | raise util.Abort(_('no matching revisions')) | |
549 | if len(roots) > 1: |
|
574 | if len(roots) > 1: | |
550 |
raise util.Abort( |
|
575 | raise util.Abort(_("can't rebase multiple roots")) | |
551 | root = roots[0] |
|
576 | root = roots[0] | |
552 |
|
577 | |||
553 | commonbase = root.ancestor(dest) |
|
578 | commonbase = root.ancestor(dest) |
@@ -67,7 +67,7 b' These fail:' | |||||
67 | [255] |
|
67 | [255] | |
68 |
|
68 | |||
69 | $ hg rebase --base 5 --source 4 |
|
69 | $ hg rebase --base 5 --source 4 | |
70 |
abort: cannot specify both a |
|
70 | abort: cannot specify both a source and a base | |
71 | [255] |
|
71 | [255] | |
72 |
|
72 | |||
73 | $ hg rebase |
|
73 | $ hg rebase |
@@ -269,4 +269,240 b' C onto A - rebase onto an ancestor:' | |||||
269 | |/ |
|
269 | |/ | |
270 | o 0: 'A' |
|
270 | o 0: 'A' | |
271 |
|
271 | |||
|
272 | $ cd .. | |||
272 |
|
273 | |||
|
274 | Test for revset | |||
|
275 | ||||
|
276 | We need a bit different graph | |||
|
277 | All destination are B | |||
|
278 | ||||
|
279 | $ hg init ah | |||
|
280 | $ cd ah | |||
|
281 | $ hg unbundle $TESTDIR/bundles/rebase-revset.hg | |||
|
282 | adding changesets | |||
|
283 | adding manifests | |||
|
284 | adding file changes | |||
|
285 | added 9 changesets with 9 changes to 9 files (+2 heads) | |||
|
286 | (run 'hg heads' to see heads, 'hg merge' to merge) | |||
|
287 | $ hg tglog | |||
|
288 | o 8: 'I' | |||
|
289 | | | |||
|
290 | o 7: 'H' | |||
|
291 | | | |||
|
292 | o 6: 'G' | |||
|
293 | | | |||
|
294 | | o 5: 'F' | |||
|
295 | | | | |||
|
296 | | o 4: 'E' | |||
|
297 | |/ | |||
|
298 | o 3: 'D' | |||
|
299 | | | |||
|
300 | o 2: 'C' | |||
|
301 | | | |||
|
302 | | o 1: 'B' | |||
|
303 | |/ | |||
|
304 | o 0: 'A' | |||
|
305 | ||||
|
306 | $ cd .. | |||
|
307 | ||||
|
308 | ||||
|
309 | Simple case with keep: | |||
|
310 | ||||
|
311 | Source on have two descendant heads but ask for one | |||
|
312 | ||||
|
313 | $ hg clone -q -u . ah ah1 | |||
|
314 | $ cd ah1 | |||
|
315 | $ hg rebase -r '2::8' -d 1 | |||
|
316 | abort: can't remove original changesets with unrebased descendants | |||
|
317 | (use --keep to keep original changesets) | |||
|
318 | [255] | |||
|
319 | $ hg rebase -r '2::8' -d 1 --keep | |||
|
320 | $ hg tglog | |||
|
321 | @ 13: 'I' | |||
|
322 | | | |||
|
323 | o 12: 'H' | |||
|
324 | | | |||
|
325 | o 11: 'G' | |||
|
326 | | | |||
|
327 | o 10: 'D' | |||
|
328 | | | |||
|
329 | o 9: 'C' | |||
|
330 | | | |||
|
331 | | o 8: 'I' | |||
|
332 | | | | |||
|
333 | | o 7: 'H' | |||
|
334 | | | | |||
|
335 | | o 6: 'G' | |||
|
336 | | | | |||
|
337 | | | o 5: 'F' | |||
|
338 | | | | | |||
|
339 | | | o 4: 'E' | |||
|
340 | | |/ | |||
|
341 | | o 3: 'D' | |||
|
342 | | | | |||
|
343 | | o 2: 'C' | |||
|
344 | | | | |||
|
345 | o | 1: 'B' | |||
|
346 | |/ | |||
|
347 | o 0: 'A' | |||
|
348 | ||||
|
349 | ||||
|
350 | $ cd .. | |||
|
351 | ||||
|
352 | Base on have one descendant heads we ask for but common ancestor have two | |||
|
353 | ||||
|
354 | $ hg clone -q -u . ah ah2 | |||
|
355 | $ cd ah2 | |||
|
356 | $ hg rebase -r '3::8' -d 1 | |||
|
357 | abort: can't remove original changesets with unrebased descendants | |||
|
358 | (use --keep to keep original changesets) | |||
|
359 | [255] | |||
|
360 | $ hg rebase -r '3::8' -d 1 --keep | |||
|
361 | $ hg tglog | |||
|
362 | @ 12: 'I' | |||
|
363 | | | |||
|
364 | o 11: 'H' | |||
|
365 | | | |||
|
366 | o 10: 'G' | |||
|
367 | | | |||
|
368 | o 9: 'D' | |||
|
369 | |\ | |||
|
370 | | | o 8: 'I' | |||
|
371 | | | | | |||
|
372 | | | o 7: 'H' | |||
|
373 | | | | | |||
|
374 | | | o 6: 'G' | |||
|
375 | | | | | |||
|
376 | | | | o 5: 'F' | |||
|
377 | | | | | | |||
|
378 | | | | o 4: 'E' | |||
|
379 | | | |/ | |||
|
380 | | | o 3: 'D' | |||
|
381 | | |/ | |||
|
382 | | o 2: 'C' | |||
|
383 | | | | |||
|
384 | o | 1: 'B' | |||
|
385 | |/ | |||
|
386 | o 0: 'A' | |||
|
387 | ||||
|
388 | ||||
|
389 | $ cd .. | |||
|
390 | ||||
|
391 | rebase subset | |||
|
392 | ||||
|
393 | $ hg clone -q -u . ah ah3 | |||
|
394 | $ cd ah3 | |||
|
395 | $ hg rebase -r '3::7' -d 1 | |||
|
396 | abort: can't remove original changesets with unrebased descendants | |||
|
397 | (use --keep to keep original changesets) | |||
|
398 | [255] | |||
|
399 | $ hg rebase -r '3::7' -d 1 --keep | |||
|
400 | $ hg tglog | |||
|
401 | @ 11: 'H' | |||
|
402 | | | |||
|
403 | o 10: 'G' | |||
|
404 | | | |||
|
405 | o 9: 'D' | |||
|
406 | |\ | |||
|
407 | | | o 8: 'I' | |||
|
408 | | | | | |||
|
409 | | | o 7: 'H' | |||
|
410 | | | | | |||
|
411 | | | o 6: 'G' | |||
|
412 | | | | | |||
|
413 | | | | o 5: 'F' | |||
|
414 | | | | | | |||
|
415 | | | | o 4: 'E' | |||
|
416 | | | |/ | |||
|
417 | | | o 3: 'D' | |||
|
418 | | |/ | |||
|
419 | | o 2: 'C' | |||
|
420 | | | | |||
|
421 | o | 1: 'B' | |||
|
422 | |/ | |||
|
423 | o 0: 'A' | |||
|
424 | ||||
|
425 | ||||
|
426 | $ cd .. | |||
|
427 | ||||
|
428 | rebase subset with multiple head | |||
|
429 | ||||
|
430 | $ hg clone -q -u . ah ah4 | |||
|
431 | $ cd ah4 | |||
|
432 | $ hg rebase -r '3::(7+5)' -d 1 | |||
|
433 | abort: can't remove original changesets with unrebased descendants | |||
|
434 | (use --keep to keep original changesets) | |||
|
435 | [255] | |||
|
436 | $ hg rebase -r '3::(7+5)' -d 1 --keep | |||
|
437 | $ hg tglog | |||
|
438 | @ 13: 'H' | |||
|
439 | | | |||
|
440 | o 12: 'G' | |||
|
441 | | | |||
|
442 | | o 11: 'F' | |||
|
443 | | | | |||
|
444 | | o 10: 'E' | |||
|
445 | |/ | |||
|
446 | o 9: 'D' | |||
|
447 | |\ | |||
|
448 | | | o 8: 'I' | |||
|
449 | | | | | |||
|
450 | | | o 7: 'H' | |||
|
451 | | | | | |||
|
452 | | | o 6: 'G' | |||
|
453 | | | | | |||
|
454 | | | | o 5: 'F' | |||
|
455 | | | | | | |||
|
456 | | | | o 4: 'E' | |||
|
457 | | | |/ | |||
|
458 | | | o 3: 'D' | |||
|
459 | | |/ | |||
|
460 | | o 2: 'C' | |||
|
461 | | | | |||
|
462 | o | 1: 'B' | |||
|
463 | |/ | |||
|
464 | o 0: 'A' | |||
|
465 | ||||
|
466 | ||||
|
467 | $ cd .. | |||
|
468 | ||||
|
469 | More advanced tests | |||
|
470 | ||||
|
471 | rebase on ancestor with revset | |||
|
472 | ||||
|
473 | $ hg clone -q -u . ah ah5 | |||
|
474 | $ cd ah5 | |||
|
475 | $ hg rebase -r '6::' -d 2 | |||
|
476 | saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-backup.hg | |||
|
477 | $ hg tglog | |||
|
478 | @ 8: 'I' | |||
|
479 | | | |||
|
480 | o 7: 'H' | |||
|
481 | | | |||
|
482 | o 6: 'G' | |||
|
483 | | | |||
|
484 | | o 5: 'F' | |||
|
485 | | | | |||
|
486 | | o 4: 'E' | |||
|
487 | | | | |||
|
488 | | o 3: 'D' | |||
|
489 | |/ | |||
|
490 | o 2: 'C' | |||
|
491 | | | |||
|
492 | | o 1: 'B' | |||
|
493 | |/ | |||
|
494 | o 0: 'A' | |||
|
495 | ||||
|
496 | $ cd .. | |||
|
497 | ||||
|
498 | ||||
|
499 | rebase with multiple root. | |||
|
500 | We rebase E and G on B | |||
|
501 | We would expect heads are I, F if it was supported | |||
|
502 | ||||
|
503 | $ hg clone -q -u . ah ah6 | |||
|
504 | $ cd ah6 | |||
|
505 | $ hg rebase -r '(4+6)::' -d 1 | |||
|
506 | abort: can't rebase multiple roots | |||
|
507 | [255] | |||
|
508 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now