341 self.destancestors) |
341 self.destancestors) |
342 |
342 |
343 if dest.closesbranch() and not self.keepbranchesf: |
343 if dest.closesbranch() and not self.keepbranchesf: |
344 self.ui.status(_('reopening closed branch head %s\n') % dest) |
344 self.ui.status(_('reopening closed branch head %s\n') % dest) |
345 |
345 |
346 def _performrebase(self, tr): |
346 def _performrebase(self): |
347 repo, ui, opts = self.repo, self.ui, self.opts |
347 repo, ui, opts = self.repo, self.ui, self.opts |
348 if self.keepbranchesf: |
348 if self.keepbranchesf: |
349 # insert _savebranch at the start of extrafns so if |
349 # insert _savebranch at the start of extrafns so if |
350 # there's a user-provided extrafn it can clobber branch if |
350 # there's a user-provided extrafn it can clobber branch if |
351 # desired |
351 # desired |
393 _('changesets'), total) |
393 _('changesets'), total) |
394 p1, p2, base = defineparents(repo, rev, self.dest, |
394 p1, p2, base = defineparents(repo, rev, self.dest, |
395 self.state, |
395 self.state, |
396 self.destancestors, |
396 self.destancestors, |
397 self.obsoletenotrebased) |
397 self.obsoletenotrebased) |
398 self.storestatus(tr=tr) |
398 self.storestatus() |
399 storecollapsemsg(repo, self.collapsemsg) |
399 storecollapsemsg(repo, self.collapsemsg) |
400 if len(repo[None].parents()) == 2: |
400 if len(repo[None].parents()) == 2: |
401 repo.ui.debug('resuming interrupted rebase\n') |
401 repo.ui.debug('resuming interrupted rebase\n') |
402 else: |
402 else: |
403 try: |
403 try: |
478 self.state[rebased] > nullmerge: |
478 self.state[rebased] > nullmerge: |
479 commitmsg += '\n* %s' % repo[rebased].description() |
479 commitmsg += '\n* %s' % repo[rebased].description() |
480 editopt = True |
480 editopt = True |
481 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform) |
481 editor = cmdutil.getcommiteditor(edit=editopt, editform=editform) |
482 revtoreuse = max(self.state) |
482 revtoreuse = max(self.state) |
483 dsguard = dirstateguard.dirstateguard(repo, 'rebase') |
483 newnode = concludenode(repo, revtoreuse, p1, self.external, |
484 try: |
484 commitmsg=commitmsg, |
485 newnode = concludenode(repo, revtoreuse, p1, self.external, |
485 extrafn=_makeextrafn(self.extrafns), |
486 commitmsg=commitmsg, |
486 editor=editor, |
487 extrafn=_makeextrafn(self.extrafns), |
487 keepbranches=self.keepbranchesf, |
488 editor=editor, |
488 date=self.date) |
489 keepbranches=self.keepbranchesf, |
|
490 date=self.date) |
|
491 dsguard.close() |
|
492 release(dsguard) |
|
493 except error.InterventionRequired: |
|
494 dsguard.close() |
|
495 release(dsguard) |
|
496 raise |
|
497 except Exception: |
|
498 release(dsguard) |
|
499 raise |
|
500 |
|
501 if newnode is None: |
489 if newnode is None: |
502 newrev = self.dest |
490 newrev = self.dest |
503 else: |
491 else: |
504 newrev = repo[newnode].rev() |
492 newrev = repo[newnode].rev() |
505 for oldrev in self.state.iterkeys(): |
493 for oldrev in self.state.iterkeys(): |
732 destspace=destspace) |
720 destspace=destspace) |
733 retcode = rbsrt._preparenewrebase(dest, rebaseset) |
721 retcode = rbsrt._preparenewrebase(dest, rebaseset) |
734 if retcode is not None: |
722 if retcode is not None: |
735 return retcode |
723 return retcode |
736 |
724 |
737 with repo.transaction('rebase') as tr: |
725 rbsrt._performrebase() |
738 dsguard = dirstateguard.dirstateguard(repo, 'rebase') |
|
739 try: |
|
740 rbsrt._performrebase(tr) |
|
741 dsguard.close() |
|
742 release(dsguard) |
|
743 except error.InterventionRequired: |
|
744 dsguard.close() |
|
745 release(dsguard) |
|
746 tr.close() |
|
747 raise |
|
748 except Exception: |
|
749 release(dsguard) |
|
750 raise |
|
751 rbsrt._finishrebase() |
726 rbsrt._finishrebase() |
752 |
727 |
753 def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=None, |
728 def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=None, |
754 destspace=None): |
729 destspace=None): |
755 """use revisions argument to define destination and rebase set |
730 """use revisions argument to define destination and rebase set |
871 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None, |
846 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None, |
872 keepbranches=False, date=None): |
847 keepbranches=False, date=None): |
873 '''Commit the wd changes with parents p1 and p2. Reuse commit info from rev |
848 '''Commit the wd changes with parents p1 and p2. Reuse commit info from rev |
874 but also store useful information in extra. |
849 but also store useful information in extra. |
875 Return node of committed revision.''' |
850 Return node of committed revision.''' |
876 repo.setparents(repo[p1].node(), repo[p2].node()) |
851 dsguard = dirstateguard.dirstateguard(repo, 'rebase') |
877 ctx = repo[rev] |
852 try: |
878 if commitmsg is None: |
853 repo.setparents(repo[p1].node(), repo[p2].node()) |
879 commitmsg = ctx.description() |
854 ctx = repo[rev] |
880 keepbranch = keepbranches and repo[p1].branch() != ctx.branch() |
855 if commitmsg is None: |
881 extra = {'rebase_source': ctx.hex()} |
856 commitmsg = ctx.description() |
882 if extrafn: |
857 keepbranch = keepbranches and repo[p1].branch() != ctx.branch() |
883 extrafn(ctx, extra) |
858 extra = {'rebase_source': ctx.hex()} |
884 |
859 if extrafn: |
885 destphase = max(ctx.phase(), phases.draft) |
860 extrafn(ctx, extra) |
886 overrides = {('phases', 'new-commit'): destphase} |
861 |
887 with repo.ui.configoverride(overrides, 'rebase'): |
862 destphase = max(ctx.phase(), phases.draft) |
888 if keepbranch: |
863 overrides = {('phases', 'new-commit'): destphase} |
889 repo.ui.setconfig('ui', 'allowemptycommit', True) |
864 with repo.ui.configoverride(overrides, 'rebase'): |
890 # Commit might fail if unresolved files exist |
865 if keepbranch: |
891 if date is None: |
866 repo.ui.setconfig('ui', 'allowemptycommit', True) |
892 date = ctx.date() |
867 # Commit might fail if unresolved files exist |
893 newnode = repo.commit(text=commitmsg, user=ctx.user(), |
868 if date is None: |
894 date=date, extra=extra, editor=editor) |
869 date = ctx.date() |
895 |
870 newnode = repo.commit(text=commitmsg, user=ctx.user(), |
896 repo.dirstate.setbranch(repo[newnode].branch()) |
871 date=date, extra=extra, editor=editor) |
897 return newnode |
872 |
|
873 repo.dirstate.setbranch(repo[newnode].branch()) |
|
874 dsguard.close() |
|
875 return newnode |
|
876 finally: |
|
877 release(dsguard) |
898 |
878 |
899 def rebasenode(repo, rev, p1, base, state, collapse, dest): |
879 def rebasenode(repo, rev, p1, base, state, collapse, dest): |
900 'Rebase a single revision rev on top of p1 using base as merge ancestor' |
880 'Rebase a single revision rev on top of p1 using base as merge ancestor' |
901 # Merge phase |
881 # Merge phase |
902 # Update to destination and merge it with local |
882 # Update to destination and merge it with local |