diff options
Diffstat (limited to 'mercurial/repair.py')
-rw-r--r-- | mercurial/repair.py | 73 |
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() |