Mercurial > hg
comparison hgext/rebase.py @ 31226:cf8ad0e6c0e4
rebase: move actual rebase into a single transaction
Previously, rebasing would open several transaction over the course of rebasing
several commits. Opening a transaction can have notable overhead (like copying
the dirstate) which can add up when rebasing many commits.
This patch adds a single large transaction around the actual commit rebase
operation, with a catch for intervention which serializes the current state if
we need to drop back to the terminal for user intervention. Amazingly, almost
all the tests seem to pass.
On large repos with large working copies, this can speed up rebasing 7 commits
by 25%. I'd expect the percentage to be a bit larger for rebasing even more
commits.
There are minor test changes because we're rolling back the entire transaction
during unexpected exceptions instead of just stopping mid-rebase, so there's no
more backup bundle. It also leave an unknown file in the working copy, since our
clean up 'hg update' doesn't delete unknown files.
author | Durham Goode <durham@fb.com> |
---|---|
date | Tue, 07 Mar 2017 16:27:32 -0800 |
parents | 749b057b01f3 |
children | 98658f73588a |
comparison
equal
deleted
inserted
replaced
31225:749b057b01f3 | 31226:cf8ad0e6c0e4 |
---|---|
341 self.targetancestors) | 341 self.targetancestors) |
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): | 346 def _performrebase(self, tr): |
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 |
391 _('changesets'), total) | 391 _('changesets'), total) |
392 p1, p2, base = defineparents(repo, rev, self.target, | 392 p1, p2, base = defineparents(repo, rev, self.target, |
393 self.state, | 393 self.state, |
394 self.targetancestors, | 394 self.targetancestors, |
395 self.obsoletenotrebased) | 395 self.obsoletenotrebased) |
396 self.storestatus() | 396 self.storestatus(tr=tr) |
397 storecollapsemsg(repo, self.collapsemsg) | 397 storecollapsemsg(repo, self.collapsemsg) |
398 if len(repo[None].parents()) == 2: | 398 if len(repo[None].parents()) == 2: |
399 repo.ui.debug('resuming interrupted rebase\n') | 399 repo.ui.debug('resuming interrupted rebase\n') |
400 else: | 400 else: |
401 try: | 401 try: |
709 destspace=destspace) | 709 destspace=destspace) |
710 retcode = rbsrt._preparenewrebase(dest, rebaseset) | 710 retcode = rbsrt._preparenewrebase(dest, rebaseset) |
711 if retcode is not None: | 711 if retcode is not None: |
712 return retcode | 712 return retcode |
713 | 713 |
714 rbsrt._performrebase() | 714 with repo.transaction('rebase') as tr: |
715 try: | |
716 rbsrt._performrebase(tr) | |
717 except error.InterventionRequired: | |
718 tr.close() | |
719 raise | |
715 rbsrt._finishrebase() | 720 rbsrt._finishrebase() |
716 finally: | 721 finally: |
717 release(lock, wlock) | 722 release(lock, wlock) |
718 | 723 |
719 def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=[], | 724 def _definesets(ui, repo, destf=None, srcf=None, basef=None, revf=[], |