diff -r ea97744c4801 -r c8eda7bbdcab mercurial/repair.py --- 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() +