Show More
@@ -0,0 +1,61 b'' | |||||
|
1 | #!/bin/sh | |||
|
2 | ||||
|
3 | # test stripping of filelogs where the linkrev doesn't always increase | |||
|
4 | ||||
|
5 | echo '[extensions]' >> $HGRCPATH | |||
|
6 | echo 'hgext.mq =' >> $HGRCPATH | |||
|
7 | ||||
|
8 | hg init orig | |||
|
9 | cd orig | |||
|
10 | ||||
|
11 | hidefilename() | |||
|
12 | { | |||
|
13 | sed -e 's/saving bundle to .*strip-backup/saving bundle to strip-backup/' | |||
|
14 | } | |||
|
15 | ||||
|
16 | commit() | |||
|
17 | { | |||
|
18 | hg up -qC null | |||
|
19 | count=1 | |||
|
20 | for i in "$@"; do | |||
|
21 | for f in $i; do | |||
|
22 | echo $count > $f | |||
|
23 | done | |||
|
24 | count=`expr $count + 1` | |||
|
25 | done | |||
|
26 | hg commit -qAm "$*" | |||
|
27 | } | |||
|
28 | ||||
|
29 | # 2 1 0 2 0 1 2 | |||
|
30 | commit '201 210' | |||
|
31 | ||||
|
32 | commit '102 120' '210' | |||
|
33 | ||||
|
34 | commit '021' | |||
|
35 | ||||
|
36 | commit '201' '021 120' | |||
|
37 | ||||
|
38 | commit '012 021' '102 201' '120 210' | |||
|
39 | ||||
|
40 | commit '102 120' '012 210' '021 201' | |||
|
41 | ||||
|
42 | commit '201 210' '021 120' '012 102' | |||
|
43 | ||||
|
44 | cd .. | |||
|
45 | hg clone -q -U -r -1 -r -2 -r -3 orig crossed | |||
|
46 | ||||
|
47 | for i in crossed/.hg/store/{00manifest.i,data/*.i}; do | |||
|
48 | echo $i | |||
|
49 | hg debugindex $i | |||
|
50 | echo | |||
|
51 | done | |||
|
52 | ||||
|
53 | for i in 0 1 2; do | |||
|
54 | hg clone -q -U --pull crossed $i | |||
|
55 | echo "% Trying to strip revision $i" | |||
|
56 | hg --cwd $i strip $i 2>&1 | hidefilename | |||
|
57 | echo "% Verifying" | |||
|
58 | hg --cwd $i verify | |||
|
59 | echo | |||
|
60 | done | |||
|
61 |
@@ -0,0 +1,87 b'' | |||||
|
1 | crossed/.hg/store/00manifest.i | |||
|
2 | rev offset length base linkrev nodeid p1 p2 | |||
|
3 | 0 0 112 0 0 6f105cbb914d 000000000000 000000000000 | |||
|
4 | 1 112 123 0 1 8f3d04e263e5 000000000000 000000000000 | |||
|
5 | 2 235 122 0 2 f0ef8726ac4f 000000000000 000000000000 | |||
|
6 | ||||
|
7 | crossed/.hg/store/data/012.i | |||
|
8 | rev offset length base linkrev nodeid p1 p2 | |||
|
9 | 0 0 3 0 0 b8e02f643373 000000000000 000000000000 | |||
|
10 | 1 3 3 1 1 5d9299349fc0 000000000000 000000000000 | |||
|
11 | 2 6 3 2 2 2661d26c6496 000000000000 000000000000 | |||
|
12 | ||||
|
13 | crossed/.hg/store/data/021.i | |||
|
14 | rev offset length base linkrev nodeid p1 p2 | |||
|
15 | 0 0 3 0 0 b8e02f643373 000000000000 000000000000 | |||
|
16 | 1 3 3 1 2 5d9299349fc0 000000000000 000000000000 | |||
|
17 | 2 6 3 2 1 2661d26c6496 000000000000 000000000000 | |||
|
18 | ||||
|
19 | crossed/.hg/store/data/102.i | |||
|
20 | rev offset length base linkrev nodeid p1 p2 | |||
|
21 | 0 0 3 0 1 b8e02f643373 000000000000 000000000000 | |||
|
22 | 1 3 3 1 0 5d9299349fc0 000000000000 000000000000 | |||
|
23 | 2 6 3 2 2 2661d26c6496 000000000000 000000000000 | |||
|
24 | ||||
|
25 | crossed/.hg/store/data/120.i | |||
|
26 | rev offset length base linkrev nodeid p1 p2 | |||
|
27 | 0 0 3 0 1 b8e02f643373 000000000000 000000000000 | |||
|
28 | 1 3 3 1 2 5d9299349fc0 000000000000 000000000000 | |||
|
29 | 2 6 3 2 0 2661d26c6496 000000000000 000000000000 | |||
|
30 | ||||
|
31 | crossed/.hg/store/data/201.i | |||
|
32 | rev offset length base linkrev nodeid p1 p2 | |||
|
33 | 0 0 3 0 2 b8e02f643373 000000000000 000000000000 | |||
|
34 | 1 3 3 1 0 5d9299349fc0 000000000000 000000000000 | |||
|
35 | 2 6 3 2 1 2661d26c6496 000000000000 000000000000 | |||
|
36 | ||||
|
37 | crossed/.hg/store/data/210.i | |||
|
38 | rev offset length base linkrev nodeid p1 p2 | |||
|
39 | 0 0 3 0 2 b8e02f643373 000000000000 000000000000 | |||
|
40 | 1 3 3 1 1 5d9299349fc0 000000000000 000000000000 | |||
|
41 | 2 6 3 2 0 2661d26c6496 000000000000 000000000000 | |||
|
42 | ||||
|
43 | % Trying to strip revision 0 | |||
|
44 | saving bundle to strip-backup/cbb8c2f0a2e3-backup | |||
|
45 | saving bundle to strip-backup/cbb8c2f0a2e3-temp | |||
|
46 | adding branch | |||
|
47 | adding changesets | |||
|
48 | adding manifests | |||
|
49 | adding file changes | |||
|
50 | added 2 changesets with 12 changes to 6 files (+1 heads) | |||
|
51 | % Verifying | |||
|
52 | checking changesets | |||
|
53 | checking manifests | |||
|
54 | crosschecking files in changesets and manifests | |||
|
55 | checking files | |||
|
56 | 6 files, 2 changesets, 12 total revisions | |||
|
57 | ||||
|
58 | % Trying to strip revision 1 | |||
|
59 | saving bundle to strip-backup/124ecc0cbec9-backup | |||
|
60 | saving bundle to strip-backup/124ecc0cbec9-temp | |||
|
61 | adding branch | |||
|
62 | adding changesets | |||
|
63 | adding manifests | |||
|
64 | adding file changes | |||
|
65 | added 1 changesets with 10 changes to 6 files (+1 heads) | |||
|
66 | % Verifying | |||
|
67 | checking changesets | |||
|
68 | checking manifests | |||
|
69 | crosschecking files in changesets and manifests | |||
|
70 | checking files | |||
|
71 | 6 files, 2 changesets, 12 total revisions | |||
|
72 | ||||
|
73 | % Trying to strip revision 2 | |||
|
74 | saving bundle to strip-backup/f6439b304a1a-backup | |||
|
75 | saving bundle to strip-backup/f6439b304a1a-temp | |||
|
76 | adding branch | |||
|
77 | adding changesets | |||
|
78 | adding manifests | |||
|
79 | adding file changes | |||
|
80 | added 0 changesets with 6 changes to 4 files | |||
|
81 | % Verifying | |||
|
82 | checking changesets | |||
|
83 | checking manifests | |||
|
84 | crosschecking files in changesets and manifests | |||
|
85 | checking files | |||
|
86 | 6 files, 2 changesets, 12 total revisions | |||
|
87 |
@@ -21,9 +21,9 b' def _limitheads(cl, stoprev):' | |||||
21 | seen[p] = 1 |
|
21 | seen[p] = 1 | |
22 | return heads |
|
22 | return heads | |
23 |
|
23 | |||
24 | def _bundle(repo, bases, heads, node, suffix): |
|
24 | def _bundle(repo, bases, heads, node, suffix, extranodes=None): | |
25 | """create a bundle with the specified revisions as a backup""" |
|
25 | """create a bundle with the specified revisions as a backup""" | |
26 | cg = repo.changegroupsubset(bases, heads, 'strip') |
|
26 | cg = repo.changegroupsubset(bases, heads, 'strip', extranodes) | |
27 | backupdir = repo.join("strip-backup") |
|
27 | backupdir = repo.join("strip-backup") | |
28 | if not os.path.isdir(backupdir): |
|
28 | if not os.path.isdir(backupdir): | |
29 | os.mkdir(backupdir) |
|
29 | os.mkdir(backupdir) | |
@@ -44,6 +44,42 b' def _collectfilenodes(repo, striprev):' | |||||
44 |
|
44 | |||
45 | return filenodes |
|
45 | return filenodes | |
46 |
|
46 | |||
|
47 | def _collectextranodes(repo, files, link): | |||
|
48 | """return the nodes that have to be saved before the strip""" | |||
|
49 | def collectone(revlog): | |||
|
50 | extra = [] | |||
|
51 | startrev = count = revlog.count() | |||
|
52 | # find the truncation point of the revlog | |||
|
53 | for i in xrange(0, count): | |||
|
54 | node = revlog.node(i) | |||
|
55 | lrev = revlog.linkrev(node) | |||
|
56 | if lrev >= link: | |||
|
57 | startrev = i + 1 | |||
|
58 | break | |||
|
59 | ||||
|
60 | # see if any revision after that point has a linkrev less than link | |||
|
61 | # (we have to manually save these guys) | |||
|
62 | for i in xrange(startrev, count): | |||
|
63 | node = revlog.node(i) | |||
|
64 | lrev = revlog.linkrev(node) | |||
|
65 | if lrev < link: | |||
|
66 | extra.append((node, cl.node(lrev))) | |||
|
67 | ||||
|
68 | return extra | |||
|
69 | ||||
|
70 | extranodes = {} | |||
|
71 | cl = repo.changelog | |||
|
72 | extra = collectone(repo.manifest) | |||
|
73 | if extra: | |||
|
74 | extranodes[1] = extra | |||
|
75 | for fname in files: | |||
|
76 | f = repo.file(fname) | |||
|
77 | extra = collectone(f) | |||
|
78 | if extra: | |||
|
79 | extranodes[fname] = extra | |||
|
80 | ||||
|
81 | return extranodes | |||
|
82 | ||||
47 | def _stripall(repo, striprev, filenodes): |
|
83 | def _stripall(repo, striprev, filenodes): | |
48 | """strip the requested nodes from the filelogs""" |
|
84 | """strip the requested nodes from the filelogs""" | |
49 | # we go in two steps here so the strip loop happens in a |
|
85 | # we go in two steps here so the strip loop happens in a | |
@@ -102,23 +138,27 b' def strip(ui, repo, node, backup="all"):' | |||||
102 | if cl.rev(x) > striprev: |
|
138 | if cl.rev(x) > striprev: | |
103 | savebases[x] = 1 |
|
139 | savebases[x] = 1 | |
104 |
|
140 | |||
|
141 | filenodes = _collectfilenodes(repo, striprev) | |||
|
142 | ||||
|
143 | extranodes = _collectextranodes(repo, filenodes, striprev) | |||
|
144 | ||||
105 | # create a changegroup for all the branches we need to keep |
|
145 | # create a changegroup for all the branches we need to keep | |
106 | if backup == "all": |
|
146 | if backup == "all": | |
107 | _bundle(repo, [node], cl.heads(), node, 'backup') |
|
147 | _bundle(repo, [node], cl.heads(), node, 'backup') | |
108 | if saveheads: |
|
148 | if saveheads or extranodes: | |
109 |
chgrpfile = _bundle(repo, savebases.keys(), saveheads, node, 'temp' |
|
149 | chgrpfile = _bundle(repo, savebases.keys(), saveheads, node, 'temp', | |
|
150 | extranodes) | |||
110 |
|
151 | |||
111 | filenodes = _collectfilenodes(repo, striprev) |
|
|||
112 | _stripall(repo, striprev, filenodes) |
|
152 | _stripall(repo, striprev, filenodes) | |
113 |
|
153 | |||
114 | change = cl.read(node) |
|
154 | change = cl.read(node) | |
115 | cl.strip(striprev, striprev) |
|
155 | cl.strip(striprev, striprev) | |
116 | repo.manifest.strip(repo.manifest.rev(change[0]), striprev) |
|
156 | repo.manifest.strip(repo.manifest.rev(change[0]), striprev) | |
117 | if saveheads: |
|
157 | if saveheads or extranodes: | |
118 | ui.status("adding branch\n") |
|
158 | ui.status("adding branch\n") | |
119 | f = open(chgrpfile, "rb") |
|
159 | f = open(chgrpfile, "rb") | |
120 | gen = changegroup.readbundle(f, chgrpfile) |
|
160 | gen = changegroup.readbundle(f, chgrpfile) | |
121 | repo.addchangegroup(gen, 'strip', 'bundle:' + chgrpfile) |
|
161 | repo.addchangegroup(gen, 'strip', 'bundle:' + chgrpfile, True) | |
122 | f.close() |
|
162 | f.close() | |
123 | if backup != "strip": |
|
163 | if backup != "strip": | |
124 | os.unlink(chgrpfile) |
|
164 | os.unlink(chgrpfile) |
@@ -1238,20 +1238,17 b' class revlog(object):' | |||||
1238 | return node |
|
1238 | return node | |
1239 |
|
1239 | |||
1240 | def strip(self, rev, minlink): |
|
1240 | def strip(self, rev, minlink): | |
1241 |
if self.count() == 0 |
|
1241 | if self.count() == 0: | |
1242 | return |
|
1242 | return | |
1243 |
|
1243 | |||
1244 | if isinstance(self.index, lazyindex): |
|
1244 | if isinstance(self.index, lazyindex): | |
1245 | self._loadindexmap() |
|
1245 | self._loadindexmap() | |
1246 |
|
1246 | |||
1247 | # When stripping away a revision, we need to make sure it |
|
1247 | for rev in xrange(0, self.count()): | |
1248 | # does not actually belong to an older changeset. |
|
1248 | if self.index[rev][4] >= minlink: | |
1249 | # The minlink parameter defines the oldest revision |
|
1249 | break | |
1250 | # we're allowed to strip away. |
|
1250 | else: | |
1251 | while minlink > self.index[rev][4]: |
|
1251 | return | |
1252 | rev += 1 |
|
|||
1253 | if rev >= self.count(): |
|
|||
1254 | return |
|
|||
1255 |
|
1252 | |||
1256 | # first truncate the files on disk |
|
1253 | # first truncate the files on disk | |
1257 | end = self.start(rev) |
|
1254 | end = self.start(rev) |
General Comments 0
You need to be logged in to leave comments.
Login now