Mercurial > public > mercurial-scm > hg-stable
diff mercurial/repair.py @ 17013:c8eda7bbdcab
strip: incrementally update the branchheads cache after a strip
This function augments strip to incrementally update the branchheads cache
rather than recompute it from scratch. This speeds up the performance of strip
and rebase on repos with long history. The performance optimization only
happens if the revisions stripped are all on the same branch and the parents of
the stripped revisions are also on that same branch.
This adds a few test cases, particularly one that reproduces the extra heads
that mpm observed.
author | Joshua Redstone <joshua.redstone@fb.com> |
---|---|
date | Fri, 18 May 2012 12:45:47 -0700 |
parents | 1093ad1e8903 |
children | ec7b9bec19c9 |
line wrap: on
line diff
--- a/mercurial/repair.py Fri Jun 01 08:56:17 2012 -0700 +++ b/mercurial/repair.py Fri May 18 12:45:47 2012 -0700 @@ -56,6 +56,11 @@ return s def strip(ui, repo, nodelist, backup="all", topic='backup'): + # It simplifies the logic around updating the branchheads cache if we only + # have to consider the effect of the stripped revisions and not revisions + # missing because the cache is out-of-date. + repo.updatebranchcache() + cl = repo.changelog # TODO handle undo of merge sets if isinstance(nodelist, str): @@ -63,6 +68,17 @@ striplist = [cl.rev(node) for node in nodelist] striprev = min(striplist) + # Generate set of branches who will have nodes stripped. + striprevs = repo.revs("%ld::", striplist) + stripbranches = set([repo[rev].branch() for rev in striprevs]) + + # Set of potential new heads resulting from the strip. The parents of any + # node removed could be a new head because the node to be removed could have + # been the only child of the parent. + newheadrevs = repo.revs("parents(%ld::) - %ld::", striprevs, striprevs) + newheadnodes = set([cl.node(rev) for rev in newheadrevs]) + newheadbranches = set([repo[rev].branch() for rev in newheadrevs]) + keeppartialbundle = backup == 'strip' # Some revisions with rev > striprev may not be descendants of striprev. @@ -169,4 +185,11 @@ % chgrpfile) raise - repo.destroyed() + if len(stripbranches) == 1 and len(newheadbranches) == 1 \ + and stripbranches == newheadbranches: + repo.destroyed(newheadnodes) + else: + # Multiple branches involved in strip. Will allow branchcache to become + # invalid and later on rebuilt from scratch + repo.destroyed() +