##// END OF EJS Templates
rebase: introduce support for automatically rebasing orphan changes...
Augie Fackler -
r37805:92213f67 default
parent child Browse files
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