Show More
@@ -108,6 +108,25 b' def _revsetdestrebase(repo, subset, x):' | |||||
108 | sourceset = revset.getset(repo, smartset.fullreposet(repo), x) |
|
108 | sourceset = revset.getset(repo, smartset.fullreposet(repo), x) | |
109 | return subset & smartset.baseset([_destrebase(repo, sourceset)]) |
|
109 | return subset & smartset.baseset([_destrebase(repo, sourceset)]) | |
110 |
|
110 | |||
|
111 | @revsetpredicate('_destautoorphanrebase') | |||
|
112 | def _revsetdestautoorphanrebase(repo, subset, x): | |||
|
113 | """automatic rebase destination for a single orphan revision""" | |||
|
114 | unfi = repo.unfiltered() | |||
|
115 | obsoleted = unfi.revs('obsolete()') | |||
|
116 | ||||
|
117 | src = revset.getset(repo, subset, x).first() | |||
|
118 | ||||
|
119 | # Empty src or already obsoleted - Do not return a destination | |||
|
120 | if not src or src in obsoleted: | |||
|
121 | return smartset.baseset() | |||
|
122 | dests = destutil.orphanpossibledestination(repo, src) | |||
|
123 | if len(dests) > 1: | |||
|
124 | raise error.Abort( | |||
|
125 | _("ambiguous automatic rebase: %r could end up on any of %r") % ( | |||
|
126 | src, dests)) | |||
|
127 | # We have zero or one destination, so we can just return here. | |||
|
128 | return smartset.baseset(dests) | |||
|
129 | ||||
111 | def _ctxdesc(ctx): |
|
130 | def _ctxdesc(ctx): | |
112 | """short description for a context""" |
|
131 | """short description for a context""" | |
113 | desc = '%d:%s "%s"' % (ctx.rev(), ctx, |
|
132 | desc = '%d:%s "%s"' % (ctx.rev(), ctx, | |
@@ -651,7 +670,10 b' class rebaseruntime(object):' | |||||
651 | ('i', 'interactive', False, _('(DEPRECATED)')), |
|
670 | ('i', 'interactive', False, _('(DEPRECATED)')), | |
652 | ('t', 'tool', '', _('specify merge tool')), |
|
671 | ('t', 'tool', '', _('specify merge tool')), | |
653 | ('c', 'continue', False, _('continue an interrupted rebase')), |
|
672 | ('c', 'continue', False, _('continue an interrupted rebase')), | |
654 |
('a', 'abort', False, _('abort an interrupted rebase')) |
|
673 | ('a', 'abort', False, _('abort an interrupted rebase')), | |
|
674 | ('', 'auto-orphans', '', _('automatically rebase orphan revisions ' | |||
|
675 | 'in the specified revset (EXPERIMENTAL)')), | |||
|
676 | ] + | |||
655 | cmdutil.formatteropts, |
|
677 | cmdutil.formatteropts, | |
656 | _('[-s REV | -b REV] [-d REV] [OPTION]')) |
|
678 | _('[-s REV | -b REV] [-d REV] [OPTION]')) | |
657 | def rebase(ui, repo, **opts): |
|
679 | def rebase(ui, repo, **opts): | |
@@ -783,6 +805,15 b' def rebase(ui, repo, **opts):' | |||||
783 | # fail the entire transaction.) |
|
805 | # fail the entire transaction.) | |
784 | inmemory = False |
|
806 | inmemory = False | |
785 |
|
807 | |||
|
808 | if opts.get('auto_orphans'): | |||
|
809 | for key in opts: | |||
|
810 | if key != 'auto_orphans' and opts.get(key): | |||
|
811 | raise error.Abort(_('--auto-orphans is incompatible with %s') % | |||
|
812 | ('--' + key)) | |||
|
813 | userrevs = list(repo.revs(opts.get('auto_orphans'))) | |||
|
814 | opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] | |||
|
815 | opts['dest'] = '_destautoorphanrebase(SRC)' | |||
|
816 | ||||
786 | if inmemory: |
|
817 | if inmemory: | |
787 | try: |
|
818 | try: | |
788 | # in-memory merge doesn't support conflicts, so if we hit any, abort |
|
819 | # in-memory merge doesn't support conflicts, so if we hit any, abort |
@@ -16,6 +16,39 b' from . import (' | |||||
16 | stack |
|
16 | stack | |
17 | ) |
|
17 | ) | |
18 |
|
18 | |||
|
19 | def orphanpossibledestination(repo, rev): | |||
|
20 | """Return all changesets that may be a new parent for orphan `rev`. | |||
|
21 | ||||
|
22 | This function works fine on non-orphan revisions, it's just silly | |||
|
23 | because there's no destination implied by obsolete markers, so | |||
|
24 | it'll return nothing. | |||
|
25 | """ | |||
|
26 | tonode = repo.changelog.node | |||
|
27 | parents = repo.changelog.parentrevs | |||
|
28 | torev = repo.changelog.rev | |||
|
29 | dest = set() | |||
|
30 | tovisit = list(parents(rev)) | |||
|
31 | while tovisit: | |||
|
32 | r = tovisit.pop() | |||
|
33 | succsets = obsutil.successorssets(repo, tonode(r)) | |||
|
34 | if not succsets: | |||
|
35 | # if there are no successors for r, r was probably pruned | |||
|
36 | # and we should walk up to r's parents to try and find | |||
|
37 | # some successors. | |||
|
38 | tovisit.extend(parents(r)) | |||
|
39 | else: | |||
|
40 | # We should probably pick only one destination from split | |||
|
41 | # (case where '1 < len(ss)'), This could be the currently | |||
|
42 | # tipmost, but the correct result is less clear when | |||
|
43 | # results of the split have been moved such that they | |||
|
44 | # reside on multiple branches. | |||
|
45 | for ss in succsets: | |||
|
46 | for n in ss: | |||
|
47 | dr = torev(n) | |||
|
48 | if dr != -1: | |||
|
49 | dest.add(dr) | |||
|
50 | return dest | |||
|
51 | ||||
19 | def _destupdateobs(repo, clean): |
|
52 | def _destupdateobs(repo, clean): | |
20 | """decide of an update destination from obsolescence markers""" |
|
53 | """decide of an update destination from obsolescence markers""" | |
21 | node = None |
|
54 | node = None |
@@ -482,7 +482,34 b' Test that rewriting leaving instability ' | |||||
482 | |/ |
|
482 | |/ | |
483 | o 0:cd010b8cd998 A |
|
483 | o 0:cd010b8cd998 A | |
484 |
|
484 | |||
|
485 | $ cd .. | |||
|
486 | $ cp -R hidden stabilize | |||
|
487 | $ cd stabilize | |||
|
488 | $ hg rebase --auto-orphans '0::' -d 10 | |||
|
489 | abort: --auto-orphans is incompatible with --dest | |||
|
490 | [255] | |||
|
491 | $ hg rebase --auto-orphans '0::' | |||
|
492 | rebasing 9:cf44d2f5a9f4 "D" | |||
|
493 | $ hg log -G | |||
|
494 | o 12:7e3935feaa68 D | |||
|
495 | | | |||
|
496 | o 11:0d8f238b634c C | |||
|
497 | | | |||
|
498 | o 10:7c6027df6a99 B | |||
|
499 | | | |||
|
500 | @ 7:02de42196ebe H | |||
|
501 | | | |||
|
502 | | o 6:eea13746799a G | |||
|
503 | |/| | |||
|
504 | o | 5:24b6387c8c8c F | |||
|
505 | | | | |||
|
506 | | o 4:9520eea781bc E | |||
|
507 | |/ | |||
|
508 | o 0:cd010b8cd998 A | |||
|
509 | ||||
485 |
|
510 | |||
|
511 | $ cd ../hidden | |||
|
512 | $ rm -r ../stabilize | |||
486 |
|
513 | |||
487 | Test multiple root handling |
|
514 | Test multiple root handling | |
488 | ------------------------------------ |
|
515 | ------------------------------------ |
General Comments 0
You need to be logged in to leave comments.
Login now