comparison hgext/rebase.py @ 28136:5853878bbc2a

rebase: extract rebaseset and destination computation in a function The whole rebase function is gargantuan and this computation is almost 100 lines long. We extract it in a dedicated function as it is independent from the rest of the rebase code. Having it in its own function will make it easier to rework the default destination logic.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 09 Feb 2016 23:49:55 +0000
parents 6025ddb4e649
children c7e8948627f3
comparison
equal deleted inserted replaced
28135:ecfa82447162 28136:5853878bbc2a
275 raise error.Abort(msg, hint=hint) 275 raise error.Abort(msg, hint=hint)
276 if abortf: 276 if abortf:
277 return abort(repo, originalwd, target, state, 277 return abort(repo, originalwd, target, state,
278 activebookmark=activebookmark) 278 activebookmark=activebookmark)
279 else: 279 else:
280 if srcf and basef: 280 dest, rebaseset = _definesets(ui, repo, destf, srcf, basef, revf)
281 raise error.Abort(_('cannot specify both a ' 281 if dest is None:
282 'source and a base')) 282 return _nothingtorebase()
283 if revf and basef:
284 raise error.Abort(_('cannot specify both a '
285 'revision and a base'))
286 if revf and srcf:
287 raise error.Abort(_('cannot specify both a '
288 'revision and a source'))
289
290 cmdutil.checkunfinished(repo)
291 cmdutil.bailifchanged(repo)
292
293 if destf:
294 dest = scmutil.revsingle(repo, destf)
295 else:
296 dest = repo[_destrebase(repo)]
297 destf = str(dest)
298
299 if revf:
300 rebaseset = scmutil.revrange(repo, revf)
301 if not rebaseset:
302 ui.status(_('empty "rev" revision set - '
303 'nothing to rebase\n'))
304 return _nothingtorebase()
305 elif srcf:
306 src = scmutil.revrange(repo, [srcf])
307 if not src:
308 ui.status(_('empty "source" revision set - '
309 'nothing to rebase\n'))
310 return _nothingtorebase()
311 rebaseset = repo.revs('(%ld)::', src)
312 assert rebaseset
313 else:
314 base = scmutil.revrange(repo, [basef or '.'])
315 if not base:
316 ui.status(_('empty "base" revision set - '
317 "can't compute rebase set\n"))
318 return _nothingtorebase()
319 commonanc = repo.revs('ancestor(%ld, %d)', base, dest).first()
320 if commonanc is not None:
321 rebaseset = repo.revs('(%d::(%ld) - %d)::',
322 commonanc, base, commonanc)
323 else:
324 rebaseset = []
325
326 if not rebaseset:
327 # transform to list because smartsets are not comparable to
328 # lists. This should be improved to honor laziness of
329 # smartset.
330 if list(base) == [dest.rev()]:
331 if basef:
332 ui.status(_('nothing to rebase - %s is both "base"'
333 ' and destination\n') % dest)
334 else:
335 ui.status(_('nothing to rebase - working directory '
336 'parent is also destination\n'))
337 elif not repo.revs('%ld - ::%d', base, dest):
338 if basef:
339 ui.status(_('nothing to rebase - "base" %s is '
340 'already an ancestor of destination '
341 '%s\n') %
342 ('+'.join(str(repo[r]) for r in base),
343 dest))
344 else:
345 ui.status(_('nothing to rebase - working '
346 'directory parent is already an '
347 'ancestor of destination %s\n') % dest)
348 else: # can it happen?
349 ui.status(_('nothing to rebase from %s to %s\n') %
350 ('+'.join(str(repo[r]) for r in base), dest))
351 return _nothingtorebase()
352 283
353 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt) 284 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
354 if (not (keepf or allowunstable) 285 if (not (keepf or allowunstable)
355 and repo.revs('first(children(%ld) - %ld)', 286 and repo.revs('first(children(%ld) - %ld)',
356 rebaseset, rebaseset)): 287 rebaseset, rebaseset)):
589 bookmarks.activate(repo, activebookmark) 520 bookmarks.activate(repo, activebookmark)
590 521
591 finally: 522 finally:
592 release(lock, wlock) 523 release(lock, wlock)
593 524
525 def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=[]):
526 """use revisions argument to define destination and rebase set
527 """
528 if srcf and basef:
529 raise error.Abort(_('cannot specify both a source and a base'))
530 if revf and basef:
531 raise error.Abort(_('cannot specify both a revision and a base'))
532 if revf and srcf:
533 raise error.Abort(_('cannot specify both a revision and a source'))
534
535 cmdutil.checkunfinished(repo)
536 cmdutil.bailifchanged(repo)
537
538 if destf:
539 dest = scmutil.revsingle(repo, destf)
540 else:
541 dest = repo[_destrebase(repo)]
542 destf = str(dest)
543
544 if revf:
545 rebaseset = scmutil.revrange(repo, revf)
546 if not rebaseset:
547 ui.status(_('empty "rev" revision set - nothing to rebase\n'))
548 return None, None
549 elif srcf:
550 src = scmutil.revrange(repo, [srcf])
551 if not src:
552 ui.status(_('empty "source" revision set - nothing to rebase\n'))
553 return None, None
554 rebaseset = repo.revs('(%ld)::', src)
555 assert rebaseset
556 else:
557 base = scmutil.revrange(repo, [basef or '.'])
558 if not base:
559 ui.status(_('empty "base" revision set - '
560 "can't compute rebase set\n"))
561 return None, None
562 commonanc = repo.revs('ancestor(%ld, %d)', base, dest).first()
563 if commonanc is not None:
564 rebaseset = repo.revs('(%d::(%ld) - %d)::',
565 commonanc, base, commonanc)
566 else:
567 rebaseset = []
568
569 if not rebaseset:
570 # transform to list because smartsets are not comparable to
571 # lists. This should be improved to honor laziness of
572 # smartset.
573 if list(base) == [dest.rev()]:
574 if basef:
575 ui.status(_('nothing to rebase - %s is both "base"'
576 ' and destination\n') % dest)
577 else:
578 ui.status(_('nothing to rebase - working directory '
579 'parent is also destination\n'))
580 elif not repo.revs('%ld - ::%d', base, dest):
581 if basef:
582 ui.status(_('nothing to rebase - "base" %s is '
583 'already an ancestor of destination '
584 '%s\n') %
585 ('+'.join(str(repo[r]) for r in base),
586 dest))
587 else:
588 ui.status(_('nothing to rebase - working '
589 'directory parent is already an '
590 'ancestor of destination %s\n') % dest)
591 else: # can it happen?
592 ui.status(_('nothing to rebase from %s to %s\n') %
593 ('+'.join(str(repo[r]) for r in base), dest))
594 return None, None
595 return dest, rebaseset
596
594 def externalparent(repo, state, targetancestors): 597 def externalparent(repo, state, targetancestors):
595 """Return the revision that should be used as the second parent 598 """Return the revision that should be used as the second parent
596 when the revisions in state is collapsed on top of targetancestors. 599 when the revisions in state is collapsed on top of targetancestors.
597 Abort if there is more than one parent. 600 Abort if there is more than one parent.
598 """ 601 """