##// END OF EJS Templates
rebase: use revset as soon as possible in internal logic...
Pierre-Yves David -
r15267:3bfdfefe default
parent child Browse files
Show More
@@ -165,7 +165,27 b' def rebase(ui, repo, **opts):'
165 165 raise util.Abort(_('cannot specify a base with detach'))
166 166
167 167 cmdutil.bailifchanged(repo)
168 result = buildstate(repo, destf, srcf, basef, detachf)
168
169 if not destf:
170 # Destination defaults to the latest revision in the current branch
171 branch = repo[None].branch()
172 dest = repo[branch]
173 else:
174 dest = repo[destf]
175
176 if srcf:
177 revsetargs = ('(%s)::', srcf)
178 else:
179 base = basef or '.'
180 revsetargs = ('(children(ancestor(%s, %d)) and ::(%s))::',
181 base, dest, base)
182
183 rebaseset = [c.rev() for c in repo.set(*revsetargs)]
184 if rebaseset:
185 result = buildstate(repo, dest, rebaseset, detachf)
186 else:
187 repo.ui.debug(_('base is ancestor of destination'))
188 result = None
169 189 if not result:
170 190 # Empty state built, nothing to rebase
171 191 ui.status(_('nothing to rebase\n'))
@@ -507,71 +527,47 b' def abort(repo, originalwd, target, stat'
507 527 repo.ui.warn(_('rebase aborted\n'))
508 528 return 0
509 529
510 def buildstate(repo, dest, src, base, detach):
511 'Define which revisions are going to be rebased and where'
512 targetancestors = set()
513 detachset = set()
530 def buildstate(repo, dest, rebaseset, detach):
531 '''Define which revisions are going to be rebased and where
514 532
515 if not dest:
516 # Destination defaults to the latest revision in the current branch
517 branch = repo[None].branch()
518 dest = repo[branch].rev()
519 else:
520 dest = repo[dest].rev()
533 repo: repo
534 dest: context
535 rebaseset: set of rev
536 detach: boolean'''
521 537
522 538 # This check isn't strictly necessary, since mq detects commits over an
523 539 # applied patch. But it prevents messing up the working directory when
524 540 # a partially completed rebase is blocked by mq.
525 if 'qtip' in repo.tags() and (repo[dest].node() in
541 if 'qtip' in repo.tags() and (dest.node() in
526 542 [s.node for s in repo.mq.applied]):
527 543 raise util.Abort(_('cannot rebase onto an applied mq patch'))
528 544
529 if src:
530 commonbase = repo[src].ancestor(repo[dest])
531 if commonbase == repo[src]:
545 detachset = set()
546 roots = list(repo.set('roots(%ld)', rebaseset))
547 if not roots:
548 raise util.Abort( _('no matching revisions'))
549 if len(roots) > 1:
550 raise util.Abort( _("can't rebase multiple roots"))
551 root = roots[0]
552
553 commonbase = root.ancestor(dest)
554 if commonbase == root:
532 555 raise util.Abort(_('source is ancestor of destination'))
533 if commonbase == repo[dest]:
534 samebranch = repo[src].branch() == repo[dest].branch()
535 if samebranch and repo[src] in repo[dest].children():
536 raise util.Abort(_('source is a child of destination'))
556 if commonbase == dest:
557 samebranch = root.branch() == dest.branch()
558 if samebranch and root in dest.children():
559 repo.ui.debug(_('source is a child of destination'))
560 return None
537 561 # rebase on ancestor, force detach
538 562 detach = True
539 source = repo[src].rev()
540 563 if detach:
541 # We need to keep track of source's ancestors up to the common base
542 srcancestors = set(repo.changelog.ancestors(source))
543 baseancestors = set(repo.changelog.ancestors(commonbase.rev()))
544 detachset = srcancestors - baseancestors
545 detachset.discard(commonbase.rev())
546 else:
547 if base:
548 cwd = repo[base].rev()
549 else:
550 cwd = repo['.'].rev()
551
552 if cwd == dest:
553 repo.ui.debug('source and destination are the same\n')
554 return None
564 detachset = [c.rev() for c in repo.set('::%d - ::%d - %d',
565 root, commonbase, root)]
555 566
556 targetancestors = set(repo.changelog.ancestors(dest))
557 if cwd in targetancestors:
558 repo.ui.debug('source is ancestor of destination\n')
559 return None
560
561 cwdancestors = set(repo.changelog.ancestors(cwd))
562 if dest in cwdancestors:
563 repo.ui.debug('source is descendant of destination\n')
564 return None
565
566 cwdancestors.add(cwd)
567 rebasingbranch = cwdancestors - targetancestors
568 source = min(rebasingbranch)
569
570 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, source))
571 state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
567 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, root))
568 state = dict.fromkeys(rebaseset, nullrev)
572 569 state.update(dict.fromkeys(detachset, nullmerge))
573 state[source] = nullrev
574 return repo['.'].rev(), repo[dest].rev(), state
570 return repo['.'].rev(), dest.rev(), state
575 571
576 572 def pullrebase(orig, ui, repo, *args, **opts):
577 573 'Call rebase after pull if the latter has been invoked with --rebase'
@@ -74,12 +74,12 b' Rebasing B onto H:'
74 74 $ cd ..
75 75
76 76
77 Rebasing G onto H:
77 Rebasing E onto H:
78 78
79 79 $ hg clone -q -u . a a2
80 80 $ cd a2
81 81
82 $ hg rebase --base 6 --collapse
82 $ hg rebase --source 4 --collapse
83 83 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
84 84
85 85 $ hg tglog
@@ -115,7 +115,7 b' Rebasing G onto H with custom message:'
115 115 abort: message can only be specified with collapse
116 116 [255]
117 117
118 $ hg rebase --base 6 --collapse -m 'custom message'
118 $ hg rebase --source 4 --collapse -m 'custom message'
119 119 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
120 120
121 121 $ hg tglog
@@ -51,8 +51,8 b' These fail:'
51 51 $ cd a1
52 52
53 53 $ hg rebase -s 8 -d 7
54 abort: source is a child of destination
55 [255]
54 nothing to rebase
55 [1]
56 56
57 57 $ hg rebase --continue --abort
58 58 abort: cannot use both abort and continue
@@ -76,7 +76,7 b' These fail:'
76 76
77 77 $ hg up -q 7
78 78
79 $ hg rebase
79 $ hg rebase --traceback
80 80 nothing to rebase
81 81 [1]
82 82
@@ -212,8 +212,8 b' G onto F - rebase onto an ancestor:'
212 212 $ cd a7
213 213
214 214 $ hg rebase -s 6 -d 5
215 abort: source is a child of destination
216 [255]
215 nothing to rebase
216 [1]
217 217
218 218 F onto G - rebase onto a descendant:
219 219
General Comments 0
You need to be logged in to leave comments. Login now