comparison mercurial/repair.py @ 5905:3afbd82a6c82

repair.py: don't use nested functions.
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Sat, 19 Jan 2008 18:01:16 -0200
parents ad5f97e08e1b
children f45f7390c1c5
comparison
equal deleted inserted replaced
5904:ad5f97e08e1b 5905:3afbd82a6c82
7 # of the GNU General Public License, incorporated herein by reference. 7 # of the GNU General Public License, incorporated herein by reference.
8 8
9 import changegroup, os 9 import changegroup, os
10 from node import * 10 from node import *
11 11
12 def _limitheads(cl, stoprev):
13 """return the list of all revs >= stoprev that have no children"""
14 seen = {}
15 heads = []
16
17 for r in xrange(cl.count() - 1, stoprev - 1, -1):
18 if r not in seen:
19 heads.append(r)
20 for p in cl.parentrevs(r):
21 seen[p] = 1
22 return heads
23
24 def _bundle(repo, bases, heads, node, suffix):
25 """create a bundle with the specified revisions as a backup"""
26 cg = repo.changegroupsubset(bases, heads, 'strip')
27 backupdir = repo.join("strip-backup")
28 if not os.path.isdir(backupdir):
29 os.mkdir(backupdir)
30 name = os.path.join(backupdir, "%s-%s" % (short(node), suffix))
31 repo.ui.warn("saving bundle to %s\n" % name)
32 return changegroup.writebundle(cg, name, "HG10BZ")
33
34 def _collectfilenodes(repo, striprev):
35 """find out the first node that should be stripped from each filelog"""
36 mm = repo.changectx(striprev).manifest()
37 filenodes = {}
38
39 for x in xrange(striprev, repo.changelog.count()):
40 for name in repo.changectx(x).files():
41 if name in filenodes:
42 continue
43 filenodes[name] = mm.get(name)
44
45 return filenodes
46
47 def _stripall(repo, striprev, filenodes):
48 """strip the requested nodes from the filelogs"""
49 # we go in two steps here so the strip loop happens in a
50 # sensible order. When stripping many files, this helps keep
51 # our disk access patterns under control.
52
53 files = filenodes.keys()
54 files.sort()
55 for name in files:
56 f = repo.file(name)
57 fnode = filenodes[name]
58 frev = 0
59 if fnode is not None and fnode in f.nodemap:
60 frev = f.rev(fnode)
61 f.strip(frev, striprev)
62
12 def strip(ui, repo, node, backup="all"): 63 def strip(ui, repo, node, backup="all"):
13 def limitheads(cl, stoprev):
14 """return the list of all revs >= stoprev that have no children"""
15 seen = {}
16 heads = []
17
18 for r in xrange(cl.count() - 1, stoprev - 1, -1):
19 if r not in seen:
20 heads.append(r)
21 for p in cl.parentrevs(r):
22 seen[p] = 1
23 return heads
24
25 def bundle(repo, bases, heads, node, suffix):
26 """create a bundle with the specified revisions as a backup"""
27 cg = repo.changegroupsubset(bases, heads, 'strip')
28 backupdir = repo.join("strip-backup")
29 if not os.path.isdir(backupdir):
30 os.mkdir(backupdir)
31 name = os.path.join(backupdir, "%s-%s" % (short(node), suffix))
32 repo.ui.warn("saving bundle to %s\n" % name)
33 return changegroup.writebundle(cg, name, "HG10BZ")
34
35 def collectfilenodes(repo, striprev):
36 """find out the first node that should be stripped from each filelog"""
37 mm = repo.changectx(striprev).manifest()
38 filenodes = {}
39
40 for x in xrange(striprev, repo.changelog.count()):
41 for name in repo.changectx(x).files():
42 if name in filenodes:
43 continue
44 filenodes[name] = mm.get(name)
45
46 return filenodes
47
48 def stripall(repo, striprev, filenodes):
49 """strip the requested nodes from the filelogs"""
50 # we go in two steps here so the strip loop happens in a
51 # sensible order. When stripping many files, this helps keep
52 # our disk access patterns under control.
53
54 files = filenodes.keys()
55 files.sort()
56 for name in files:
57 f = repo.file(name)
58 fnode = filenodes[name]
59 frev = 0
60 if fnode is not None and fnode in f.nodemap:
61 frev = f.rev(fnode)
62 f.strip(frev, striprev)
63
64 cl = repo.changelog 64 cl = repo.changelog
65 # TODO delete the undo files, and handle undo of merge sets 65 # TODO delete the undo files, and handle undo of merge sets
66 pp = cl.parents(node) 66 pp = cl.parents(node)
67 striprev = cl.rev(node) 67 striprev = cl.rev(node)
68 68
70 # that we actually want to keep. changegroup will be used 70 # that we actually want to keep. changegroup will be used
71 # to preserve them and add them back after the truncate 71 # to preserve them and add them back after the truncate
72 saveheads = [] 72 saveheads = []
73 savebases = {} 73 savebases = {}
74 74
75 heads = [cl.node(r) for r in limitheads(cl, striprev)] 75 heads = [cl.node(r) for r in _limitheads(cl, striprev)]
76 seen = {} 76 seen = {}
77 77
78 # search through all the heads, finding those where the revision 78 # search through all the heads, finding those where the revision
79 # we want to strip away is an ancestor. Also look for merges 79 # we want to strip away is an ancestor. Also look for merges
80 # that might be turned into new heads by the strip. 80 # that might be turned into new heads by the strip.
102 if cl.rev(x) > striprev: 102 if cl.rev(x) > striprev:
103 savebases[x] = 1 103 savebases[x] = 1
104 104
105 # create a changegroup for all the branches we need to keep 105 # create a changegroup for all the branches we need to keep
106 if backup == "all": 106 if backup == "all":
107 bundle(repo, [node], cl.heads(), node, 'backup') 107 _bundle(repo, [node], cl.heads(), node, 'backup')
108 if saveheads: 108 if saveheads:
109 chgrpfile = bundle(repo, savebases.keys(), saveheads, node, 'temp') 109 chgrpfile = _bundle(repo, savebases.keys(), saveheads, node, 'temp')
110 110
111 filenodes = collectfilenodes(repo, striprev) 111 filenodes = _collectfilenodes(repo, striprev)
112 stripall(repo, striprev, filenodes) 112 _stripall(repo, striprev, filenodes)
113 113
114 change = cl.read(node) 114 change = cl.read(node)
115 cl.strip(striprev, striprev) 115 cl.strip(striprev, striprev)
116 repo.manifest.strip(repo.manifest.rev(change[0]), striprev) 116 repo.manifest.strip(repo.manifest.rev(change[0]), striprev)
117 if saveheads: 117 if saveheads: