mercurial/repair.py
changeset 17013 c8eda7bbdcab
parent 16867 1093ad1e8903
child 17264 ec7b9bec19c9
--- 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()
+