summaryrefslogtreecommitdiff
path: root/mercurial/repair.py
diff options
context:
space:
mode:
Diffstat (limited to 'mercurial/repair.py')
-rw-r--r--mercurial/repair.py73
1 files changed, 15 insertions, 58 deletions
diff --git a/mercurial/repair.py b/mercurial/repair.py
index 9ccaa34..c95dff1 100644
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -10,7 +10,6 @@ from mercurial import changegroup, bookmarks
from mercurial.node import short
from mercurial.i18n import _
import os
-import errno
def _bundle(repo, bases, heads, node, suffix, compress=True):
"""create a bundle with the specified revisions as a backup"""
@@ -38,14 +37,14 @@ def _collectbrokencsets(repo, files, striprev):
"""return the changesets which will be broken by the truncation"""
s = set()
def collectone(revlog):
- linkgen = (revlog.linkrev(i) for i in revlog)
+ links = (revlog.linkrev(i) for i in revlog)
# find the truncation point of the revlog
- for lrev in linkgen:
+ for lrev in links:
if lrev >= striprev:
break
# see if any revision after this point has a linkrev
# less than striprev (those will be broken by strip)
- for lrev in linkgen:
+ for lrev in links:
if lrev < striprev:
s.add(lrev)
@@ -55,29 +54,10 @@ def _collectbrokencsets(repo, files, striprev):
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()
-
+def strip(ui, repo, node, backup="all"):
cl = repo.changelog
- # TODO handle undo of merge sets
- if isinstance(nodelist, str):
- nodelist = [nodelist]
- 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])
+ # TODO delete the undo files, and handle undo of merge sets
+ striprev = cl.rev(node)
keeppartialbundle = backup == 'strip'
@@ -88,10 +68,8 @@ def strip(ui, repo, nodelist, backup="all", topic='backup'):
# the list of heads and bases of the set of interesting revisions.
# (head = revision in the set that has no descendant in the set;
# base = revision in the set that has no ancestor in the set)
- tostrip = set(striplist)
- for rev in striplist:
- for desc in cl.descendants([rev]):
- tostrip.add(desc)
+ tostrip = set(cl.descendants(striprev))
+ tostrip.add(striprev)
files = _collectfiles(repo, striprev)
saverevs = _collectbrokencsets(repo, files, striprev)
@@ -107,17 +85,9 @@ def strip(ui, repo, nodelist, backup="all", topic='backup'):
# compute base nodes
if saverevs:
- descendants = set(cl.descendants(saverevs))
+ descendants = set(cl.descendants(*saverevs))
saverevs.difference_update(descendants)
savebases = [cl.node(r) for r in saverevs]
- stripbases = [cl.node(r) for r in tostrip]
- rset = ' or '.join([str(r) for r in tostrip])
- newbmtarget = repo.revs('sort(heads(ancestors(%r) - (%r)), -rev)',
- rset, rset)
- if newbmtarget:
- newbmtarget = newbmtarget[0]
- else:
- newbmtarget = '.'
bm = repo._bookmarks
updatebm = []
@@ -129,7 +99,7 @@ def strip(ui, repo, nodelist, backup="all", topic='backup'):
# create a changegroup for all the branches we need to keep
backupfile = None
if backup == "all":
- backupfile = _bundle(repo, stripbases, cl.heads(), node, topic)
+ backupfile = _bundle(repo, [node], cl.heads(), node, 'backup')
repo.ui.status(_("saved backup bundle to %s\n") % backupfile)
if saveheads or savebases:
# do not compress partial bundle if we remove it from disk later
@@ -154,7 +124,7 @@ def strip(ui, repo, nodelist, backup="all", topic='backup'):
file, troffset, ignore = tr.entries[i]
repo.sopener(file, 'a').truncate(troffset)
tr.close()
- except: # re-raises
+ except:
tr.abort()
raise
@@ -172,18 +142,11 @@ def strip(ui, repo, nodelist, backup="all", topic='backup'):
if not keeppartialbundle:
os.unlink(chgrpfile)
- # remove undo files
- for undofile in repo.undofiles():
- try:
- os.unlink(undofile)
- except OSError, e:
- if e.errno != errno.ENOENT:
- ui.warn(_('error removing %s: %s\n') % (undofile, str(e)))
-
for m in updatebm:
- bm[m] = repo[newbmtarget].node()
+ bm[m] = repo['.'].node()
bookmarks.write(repo)
- except: # re-raises
+
+ except:
if backupfile:
ui.warn(_("strip failed, full bundle stored in '%s'\n")
% backupfile)
@@ -192,10 +155,4 @@ def strip(ui, repo, nodelist, backup="all", topic='backup'):
% chgrpfile)
raise
- 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()
+ repo.destroyed()