Mercurial > hg-stable
annotate mercurial/revlog.py @ 2289:854954fd410a
Fix revlog.parseindex
parseindex could fail if read returns too little data in the right
moment (e.g. when there's still leftover data from the previous
iteration and read returns less than "s" bytes).
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Sun, 14 May 2006 18:22:12 -0300 |
parents | 3f38e872f39a |
children | 9c15f85e61b1 |
rev | line source |
---|---|
1083 | 1 """ |
2 revlog.py - storage back-end for mercurial | |
3 | |
4 This provides efficient delta storage with O(1) retrieve and append | |
5 and O(changes) merge between branches | |
6 | |
7 Copyright 2005 Matt Mackall <mpm@selenic.com> | |
8 | |
9 This software may be used and distributed according to the terms | |
10 of the GNU General Public License, incorporated herein by reference. | |
11 """ | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
12 |
1089 | 13 from node import * |
1400
cf9a1233738a
i18n first part: make '_' available for files who need it
Benoit Boissinot <benoit.boissinot@ens-lyon.org
parents:
1393
diff
changeset
|
14 from i18n import gettext as _ |
1322
b3d44e9b3092
Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1232
diff
changeset
|
15 from demandload import demandload |
1981
736b6c96bbbc
make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1941
diff
changeset
|
16 demandload(globals(), "binascii changegroup errno heapq mdiff os") |
2176
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2089
diff
changeset
|
17 demandload(globals(), "sha struct util zlib") |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
18 |
2072 | 19 # revlog version strings |
20 REVLOGV0 = 0 | |
21 REVLOGNG = 1 | |
22 | |
2073 | 23 # revlog flags |
24 REVLOGNGINLINEDATA = (1 << 16) | |
2222
c9e264b115e6
Use revlogng and inlined data files by default
mason@suse.com
parents:
2177
diff
changeset
|
25 REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA |
c9e264b115e6
Use revlogng and inlined data files by default
mason@suse.com
parents:
2177
diff
changeset
|
26 |
c9e264b115e6
Use revlogng and inlined data files by default
mason@suse.com
parents:
2177
diff
changeset
|
27 REVLOG_DEFAULT_FORMAT = REVLOGNG |
c9e264b115e6
Use revlogng and inlined data files by default
mason@suse.com
parents:
2177
diff
changeset
|
28 REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS |
2073 | 29 |
30 def flagstr(flag): | |
31 if flag == "inline": | |
32 return REVLOGNGINLINEDATA | |
33 raise RevlogError(_("unknown revlog flag %s" % flag)) | |
34 | |
1091
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
35 def hash(text, p1, p2): |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
36 """generate a hash from the given text and its parent hashes |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
37 |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
38 This hash combines both the current file contents and its history |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
39 in a manner that makes it easy to distinguish nodes with the same |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
40 content in the revision graph. |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
41 """ |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
42 l = [p1, p2] |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
43 l.sort() |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
44 s = sha.new(l[0]) |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
45 s.update(l[1]) |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
46 s.update(text) |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
47 return s.digest() |
d62130f99a73
Move hash function back to revlog from node
mpm@selenic.com
parents:
1089
diff
changeset
|
48 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
49 def compress(text): |
1083 | 50 """ generate a possibly-compressed representation of text """ |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
51 if not text: return ("", text) |
112 | 52 if len(text) < 44: |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
53 if text[0] == '\0': return ("", text) |
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
54 return ('u', text) |
112 | 55 bin = zlib.compress(text) |
56 if len(bin) > len(text): | |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
57 if text[0] == '\0': return ("", text) |
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
58 return ('u', text) |
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
59 return ("", bin) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
60 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
61 def decompress(bin): |
1083 | 62 """ decompress the given input """ |
112 | 63 if not bin: return bin |
64 t = bin[0] | |
65 if t == '\0': return bin | |
66 if t == 'x': return zlib.decompress(bin) | |
67 if t == 'u': return bin[1:] | |
1853
5ac811b720de
Fix some problems when working on broken repositories:
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1784
diff
changeset
|
68 raise RevlogError(_("unknown compression type %r") % t) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
69 |
2072 | 70 indexformatv0 = ">4l20s20s20s" |
2079 | 71 v0shaoffset = 56 |
2072 | 72 # index ng: |
73 # 6 bytes offset | |
74 # 2 bytes flags | |
75 # 4 bytes compressed length | |
76 # 4 bytes uncompressed length | |
77 # 4 bytes: base rev | |
78 # 4 bytes link rev | |
79 # 4 bytes parent 1 rev | |
80 # 4 bytes parent 2 rev | |
81 # 32 bytes: nodeid | |
82 indexformatng = ">Qiiiiii20s12x" | |
2079 | 83 ngshaoffset = 32 |
2072 | 84 versionformat = ">i" |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
85 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1551
diff
changeset
|
86 class lazyparser(object): |
1083 | 87 """ |
88 this class avoids the need to parse the entirety of large indices | |
89 """ | |
2250
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
90 |
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
91 # lazyparser is not safe to use on windows if win32 extensions not |
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
92 # available. it keeps file handle open, which make it not possible |
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
93 # to break hardlinks on local cloned repos. |
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
94 safe_to_use = os.name != 'nt' or (not util.is_win_9x() and |
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
95 hasattr(util, 'win32api')) |
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
96 |
2079 | 97 def __init__(self, dataf, size, indexformat, shaoffset): |
98 self.dataf = dataf | |
99 self.format = indexformat | |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
100 self.s = struct.calcsize(indexformat) |
2072 | 101 self.indexformat = indexformat |
2079 | 102 self.datasize = size |
103 self.l = size/self.s | |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
104 self.index = [None] * self.l |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
105 self.map = {nullid: -1} |
2079 | 106 self.allmap = 0 |
323 | 107 self.all = 0 |
2079 | 108 self.mapfind_count = 0 |
109 self.shaoffset = shaoffset | |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
110 |
2079 | 111 def loadmap(self): |
112 """ | |
113 during a commit, we need to make sure the rev being added is | |
114 not a duplicate. This requires loading the entire index, | |
115 which is fairly slow. loadmap can load up just the node map, | |
116 which takes much less time. | |
117 """ | |
118 if self.allmap: return | |
119 start = 0 | |
120 end = self.datasize | |
121 self.allmap = 1 | |
122 cur = 0 | |
123 count = 0 | |
124 blocksize = self.s * 256 | |
125 self.dataf.seek(0) | |
126 while cur < end: | |
127 data = self.dataf.read(blocksize) | |
128 off = 0 | |
129 for x in xrange(256): | |
130 n = data[off + self.shaoffset:off + self.shaoffset + 20] | |
131 self.map[n] = count | |
132 count += 1 | |
133 if count >= self.l: | |
134 break | |
135 off += self.s | |
136 cur += blocksize | |
137 | |
138 def loadblock(self, blockstart, blocksize, data=None): | |
323 | 139 if self.all: return |
2079 | 140 if data is None: |
141 self.dataf.seek(blockstart) | |
142 data = self.dataf.read(blocksize) | |
143 lend = len(data) / self.s | |
144 i = blockstart / self.s | |
145 off = 0 | |
146 for x in xrange(lend): | |
147 if self.index[i + x] == None: | |
148 b = data[off : off + self.s] | |
2080
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
149 self.index[i + x] = b |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
150 n = b[self.shaoffset:self.shaoffset + 20] |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
151 self.map[n] = i + x |
2079 | 152 off += self.s |
153 | |
154 def findnode(self, node): | |
155 """search backwards through the index file for a specific node""" | |
156 if self.allmap: return None | |
157 | |
158 # hg log will cause many many searches for the manifest | |
159 # nodes. After we get called a few times, just load the whole | |
160 # thing. | |
161 if self.mapfind_count > 8: | |
162 self.loadmap() | |
163 if node in self.map: | |
164 return node | |
165 return None | |
166 self.mapfind_count += 1 | |
167 last = self.l - 1 | |
168 while self.index[last] != None: | |
169 if last == 0: | |
170 self.all = 1 | |
171 self.allmap = 1 | |
172 return None | |
173 last -= 1 | |
174 end = (last + 1) * self.s | |
175 blocksize = self.s * 256 | |
176 while end >= 0: | |
177 start = max(end - blocksize, 0) | |
178 self.dataf.seek(start) | |
179 data = self.dataf.read(end - start) | |
180 findend = end - start | |
181 while True: | |
182 # we're searching backwards, so weh have to make sure | |
183 # we don't find a changeset where this node is a parent | |
184 off = data.rfind(node, 0, findend) | |
185 findend = off | |
186 if off >= 0: | |
187 i = off / self.s | |
188 off = i * self.s | |
189 n = data[off + self.shaoffset:off + self.shaoffset + 20] | |
190 if n == node: | |
191 self.map[n] = i + start / self.s | |
192 return node | |
193 else: | |
194 break | |
195 end -= blocksize | |
196 return None | |
197 | |
198 def loadindex(self, i=None, end=None): | |
199 if self.all: return | |
200 all = False | |
201 if i == None: | |
202 blockstart = 0 | |
203 blocksize = (512 / self.s) * self.s | |
204 end = self.datasize | |
205 all = True | |
323 | 206 else: |
2079 | 207 if end: |
208 blockstart = i * self.s | |
209 end = end * self.s | |
210 blocksize = end - blockstart | |
211 else: | |
212 blockstart = (i & ~(32)) * self.s | |
213 blocksize = self.s * 64 | |
214 end = blockstart + blocksize | |
215 while blockstart < end: | |
216 self.loadblock(blockstart, blocksize) | |
217 blockstart += blocksize | |
218 if all: self.all = True | |
515 | 219 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1551
diff
changeset
|
220 class lazyindex(object): |
1083 | 221 """a lazy version of the index array""" |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
222 def __init__(self, parser): |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
223 self.p = parser |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
224 def __len__(self): |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
225 return len(self.p.index) |
115 | 226 def load(self, pos): |
1403
bc3e66edb04c
lazyindex fix, make load handle negative indexes properly.
Eric Hopper <hopper@omnifarious.org>
parents:
1402
diff
changeset
|
227 if pos < 0: |
bc3e66edb04c
lazyindex fix, make load handle negative indexes properly.
Eric Hopper <hopper@omnifarious.org>
parents:
1402
diff
changeset
|
228 pos += len(self.p.index) |
2079 | 229 self.p.loadindex(pos) |
115 | 230 return self.p.index[pos] |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
231 def __getitem__(self, pos): |
2080
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
232 ret = self.p.index[pos] or self.load(pos) |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
233 if isinstance(ret, str): |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
234 ret = struct.unpack(self.p.indexformat, ret) |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
235 return ret |
2072 | 236 def __setitem__(self, pos, item): |
237 self.p.index[pos] = item | |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
238 def __delitem__(self, pos): |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
239 del self.p.index[pos] |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
240 def append(self, e): |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
241 self.p.index.append(e) |
515 | 242 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1551
diff
changeset
|
243 class lazymap(object): |
1083 | 244 """a lazy version of the node map""" |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
245 def __init__(self, parser): |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
246 self.p = parser |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
247 def load(self, key): |
2079 | 248 n = self.p.findnode(key) |
249 if n == None: | |
1214 | 250 raise KeyError(key) |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
251 def __contains__(self, key): |
2079 | 252 if key in self.p.map: |
253 return True | |
254 self.p.loadmap() | |
323 | 255 return key in self.p.map |
97 | 256 def __iter__(self): |
469 | 257 yield nullid |
97 | 258 for i in xrange(self.p.l): |
2080
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
259 ret = self.p.index[i] |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
260 if not ret: |
2079 | 261 self.p.loadindex(i) |
2080
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
262 ret = self.p.index[i] |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
263 if isinstance(ret, str): |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
264 ret = struct.unpack(self.p.indexformat, ret) |
1cbb14c048cb
Reduce index memory usage by storing the bare string instead of tuples
mason@suse.com
parents:
2079
diff
changeset
|
265 yield ret[-1] |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
266 def __getitem__(self, key): |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
267 try: |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
268 return self.p.map[key] |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
269 except KeyError: |
86
1b945e8ba67b
Friendlier exceptions for unknown node errors
mpm@selenic.com
parents:
84
diff
changeset
|
270 try: |
1b945e8ba67b
Friendlier exceptions for unknown node errors
mpm@selenic.com
parents:
84
diff
changeset
|
271 self.load(key) |
1b945e8ba67b
Friendlier exceptions for unknown node errors
mpm@selenic.com
parents:
84
diff
changeset
|
272 return self.p.map[key] |
1b945e8ba67b
Friendlier exceptions for unknown node errors
mpm@selenic.com
parents:
84
diff
changeset
|
273 except KeyError: |
1b945e8ba67b
Friendlier exceptions for unknown node errors
mpm@selenic.com
parents:
84
diff
changeset
|
274 raise KeyError("node " + hex(key)) |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
275 def __setitem__(self, key, val): |
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
276 self.p.map[key] = val |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
277 def __delitem__(self, key): |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
278 del self.p.map[key] |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
279 |
1073
7b35a980b982
[PATCH] raise exceptions with Exception subclasses
Bart Trojanowski <bart@jukie.net>
parents:
1062
diff
changeset
|
280 class RevlogError(Exception): pass |
7b35a980b982
[PATCH] raise exceptions with Exception subclasses
Bart Trojanowski <bart@jukie.net>
parents:
1062
diff
changeset
|
281 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1551
diff
changeset
|
282 class revlog(object): |
1083 | 283 """ |
284 the underlying revision storage object | |
285 | |
286 A revlog consists of two parts, an index and the revision data. | |
287 | |
288 The index is a file with a fixed record size containing | |
289 information on each revision, includings its nodeid (hash), the | |
290 nodeids of its parents, the position and offset of its data within | |
291 the data file, and the revision it's based on. Finally, each entry | |
292 contains a linkrev entry that can serve as a pointer to external | |
293 data. | |
294 | |
295 The revision data itself is a linear collection of data chunks. | |
296 Each chunk represents a revision and is usually represented as a | |
297 delta against the previous chunk. To bound lookup time, runs of | |
298 deltas are limited to about 2 times the length of the original | |
299 version data. This makes retrieval of a version proportional to | |
300 its size, or O(1) relative to the number of revisions. | |
301 | |
302 Both pieces of the revlog are written to in an append-only | |
303 fashion, which means we never need to rewrite a file to insert or | |
304 remove data, and can use some simple techniques to avoid the need | |
305 for locking while reading. | |
306 """ | |
2222
c9e264b115e6
Use revlogng and inlined data files by default
mason@suse.com
parents:
2177
diff
changeset
|
307 def __init__(self, opener, indexfile, datafile, |
c9e264b115e6
Use revlogng and inlined data files by default
mason@suse.com
parents:
2177
diff
changeset
|
308 defversion=REVLOG_DEFAULT_VERSION): |
1083 | 309 """ |
310 create a revlog object | |
311 | |
312 opener is a function that abstracts the file opening operation | |
313 and can be used to implement COW semantics or the like. | |
314 """ | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
315 self.indexfile = indexfile |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
316 self.datafile = datafile |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
317 self.opener = opener |
1784
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
318 |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
319 self.indexstat = None |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
320 self.cache = None |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
321 self.chunkcache = None |
2072 | 322 self.defversion = defversion |
1784
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
323 self.load() |
116
e484cd5ec282
Only use lazy indexing for big indices and avoid the overhead of the
mpm@selenic.com
parents:
115
diff
changeset
|
324 |
1784
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
325 def load(self): |
2072 | 326 v = self.defversion |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
327 try: |
1784
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
328 f = self.opener(self.indexfile) |
2079 | 329 i = f.read(4) |
330 f.seek(0) | |
1322
b3d44e9b3092
Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1232
diff
changeset
|
331 except IOError, inst: |
b3d44e9b3092
Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1232
diff
changeset
|
332 if inst.errno != errno.ENOENT: |
b3d44e9b3092
Make revlog constructor more discerning in its treatment of errors.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1232
diff
changeset
|
333 raise |
76
d993ebd69d28
Add lazy{parser,index,map} to speed up processing of index files
mpm@selenic.com
parents:
73
diff
changeset
|
334 i = "" |
1784
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
335 else: |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
336 try: |
2176
9b42304d9896
fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2089
diff
changeset
|
337 st = util.fstat(f) |
1784
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
338 except AttributeError, inst: |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
339 st = None |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
340 else: |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
341 oldst = self.indexstat |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
342 if (oldst and st.st_dev == oldst.st_dev |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
343 and st.st_ino == oldst.st_ino |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
344 and st.st_mtime == oldst.st_mtime |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
345 and st.st_ctime == oldst.st_ctime): |
2e0a288ca93e
revalidate revlog data after locking the repo (issue132)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1749
diff
changeset
|
346 return |
2072 | 347 self.indexstat = st |
2138
f5046cab9e2e
Fix revlog-ng interaction with old-http.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2089
diff
changeset
|
348 if len(i) > 0: |
f5046cab9e2e
Fix revlog-ng interaction with old-http.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2089
diff
changeset
|
349 v = struct.unpack(versionformat, i)[0] |
2073 | 350 flags = v & ~0xFFFF |
351 fmt = v & 0xFFFF | |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
352 if fmt == REVLOGV0: |
2073 | 353 if flags: |
354 raise RevlogError(_("index %s invalid flags %x for format v0" % | |
355 (self.indexfile, flags))) | |
356 elif fmt == REVLOGNG: | |
357 if flags & ~REVLOGNGINLINEDATA: | |
358 raise RevlogError(_("index %s invalid flags %x for revlogng" % | |
359 (self.indexfile, flags))) | |
360 else: | |
361 raise RevlogError(_("index %s invalid format %d" % | |
362 (self.indexfile, fmt))) | |
2072 | 363 self.version = v |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
364 if v == REVLOGV0: |
2072 | 365 self.indexformat = indexformatv0 |
2079 | 366 shaoffset = v0shaoffset |
2072 | 367 else: |
368 self.indexformat = indexformatng | |
2079 | 369 shaoffset = ngshaoffset |
116
e484cd5ec282
Only use lazy indexing for big indices and avoid the overhead of the
mpm@selenic.com
parents:
115
diff
changeset
|
370 |
2072 | 371 if i: |
2250
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
372 if (lazyparser.safe_to_use and not self.inlinedata() and |
45aef5ddcdbe
windows: revlog.lazyparser not always safe to use.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2222
diff
changeset
|
373 st and st.st_size > 10000): |
2072 | 374 # big index, let's parse it on demand |
2079 | 375 parser = lazyparser(f, st.st_size, self.indexformat, shaoffset) |
2072 | 376 self.index = lazyindex(parser) |
377 self.nodemap = lazymap(parser) | |
378 else: | |
2255
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
379 self.parseindex(f, st) |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
380 if self.version != REVLOGV0: |
2072 | 381 e = list(self.index[0]) |
382 type = self.ngtype(e[0]) | |
383 e[0] = self.offset_type(0, type) | |
384 self.index[0] = e | |
116
e484cd5ec282
Only use lazy indexing for big indices and avoid the overhead of the
mpm@selenic.com
parents:
115
diff
changeset
|
385 else: |
2072 | 386 self.nodemap = { nullid: -1} |
387 self.index = [] | |
388 | |
389 | |
2255
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
390 def parseindex(self, fp, st): |
2072 | 391 s = struct.calcsize(self.indexformat) |
392 self.index = [] | |
393 self.nodemap = {nullid: -1} | |
2073 | 394 inline = self.inlinedata() |
2072 | 395 n = 0 |
2255
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
396 leftover = None |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
397 while True: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
398 if st: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
399 data = fp.read(65536) |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
400 else: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
401 # hack for httprangereader, it doesn't do partial reads well |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
402 data = fp.read() |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
403 if not data: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
404 break |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
405 if n == 0 and self.inlinedata(): |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
406 # cache the first chunk |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
407 self.chunkcache = (0, data) |
2289
854954fd410a
Fix revlog.parseindex
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2255
diff
changeset
|
408 if leftover: |
854954fd410a
Fix revlog.parseindex
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2255
diff
changeset
|
409 data = leftover + data |
854954fd410a
Fix revlog.parseindex
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2255
diff
changeset
|
410 leftover = None |
2255
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
411 off = 0 |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
412 l = len(data) |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
413 while off < l: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
414 if l - off < s: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
415 leftover = data[off:] |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
416 break |
2289
854954fd410a
Fix revlog.parseindex
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2255
diff
changeset
|
417 cur = data[off:off + s] |
854954fd410a
Fix revlog.parseindex
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2255
diff
changeset
|
418 off += s |
2255
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
419 e = struct.unpack(self.indexformat, cur) |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
420 self.index.append(e) |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
421 self.nodemap[e[-1]] = n |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
422 n += 1 |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
423 if inline: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
424 off += e[1] |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
425 if off > l: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
426 # some things don't seek well, just read it |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
427 fp.read(off - l) |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
428 if not st: |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
429 break |
3f38e872f39a
Reduce ram used for very large inlined index files
mason@suse.com
parents:
2250
diff
changeset
|
430 |
116
e484cd5ec282
Only use lazy indexing for big indices and avoid the overhead of the
mpm@selenic.com
parents:
115
diff
changeset
|
431 |
2072 | 432 def ngoffset(self, q): |
433 if q & 0xFFFF: | |
434 raise RevlogError(_('%s: incompatible revision flag %x') % | |
2141
ed631e83fa06
Corrected error message for incompatible revision flags.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2138
diff
changeset
|
435 (self.indexfile, q)) |
2072 | 436 return long(q >> 16) |
437 | |
438 def ngtype(self, q): | |
439 return int(q & 0xFFFF) | |
116
e484cd5ec282
Only use lazy indexing for big indices and avoid the overhead of the
mpm@selenic.com
parents:
115
diff
changeset
|
440 |
2072 | 441 def offset_type(self, offset, type): |
442 return long(long(offset) << 16 | type) | |
443 | |
2079 | 444 def loadindex(self, start, end): |
445 """load a block of indexes all at once from the lazy parser""" | |
446 if isinstance(self.index, lazyindex): | |
447 self.index.p.loadindex(start, end) | |
448 | |
2072 | 449 def loadindexmap(self): |
450 """loads both the map and the index from the lazy parser""" | |
451 if isinstance(self.index, lazyindex): | |
452 p = self.index.p | |
2079 | 453 p.loadindex() |
454 self.nodemap = p.map | |
455 | |
456 def loadmap(self): | |
457 """loads the map from the lazy parser""" | |
458 if isinstance(self.nodemap, lazymap): | |
459 self.nodemap.p.loadmap() | |
460 self.nodemap = self.nodemap.p.map | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
461 |
2073 | 462 def inlinedata(self): return self.version & REVLOGNGINLINEDATA |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
463 def tip(self): return self.node(len(self.index) - 1) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
464 def count(self): return len(self.index) |
2072 | 465 def node(self, rev): |
466 return (rev < 0) and nullid or self.index[rev][-1] | |
1201
59bfbdbc38f6
revlog: raise informative exception if file is missing.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1099
diff
changeset
|
467 def rev(self, node): |
59bfbdbc38f6
revlog: raise informative exception if file is missing.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1099
diff
changeset
|
468 try: |
59bfbdbc38f6
revlog: raise informative exception if file is missing.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1099
diff
changeset
|
469 return self.nodemap[node] |
59bfbdbc38f6
revlog: raise informative exception if file is missing.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1099
diff
changeset
|
470 except KeyError: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
471 raise RevlogError(_('%s: no node %s') % (self.indexfile, hex(node))) |
2072 | 472 def linkrev(self, node): return self.index[self.rev(node)][-4] |
2 | 473 def parents(self, node): |
474 if node == nullid: return (nullid, nullid) | |
2072 | 475 r = self.rev(node) |
476 d = self.index[r][-3:-1] | |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
477 if self.version == REVLOGV0: |
2072 | 478 return d |
479 return [ self.node(x) for x in d ] | |
480 def start(self, rev): | |
481 if rev < 0: | |
482 return -1 | |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
483 if self.version != REVLOGV0: |
2072 | 484 return self.ngoffset(self.index[rev][0]) |
485 return self.index[rev][0] | |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
486 |
2072 | 487 def end(self, rev): return self.start(rev) + self.length(rev) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
488 |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
489 def size(self, rev): |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
490 """return the length of the uncompressed text for a given revision""" |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
491 l = -1 |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
492 if self.version != REVLOGV0: |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
493 l = self.index[rev][2] |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
494 if l >= 0: |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
495 return l |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
496 |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
497 t = self.revision(self.node(rev)) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
498 return len(t) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
499 |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
500 # alternate implementation, The advantage to this code is it |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
501 # will be faster for a single revision. But, the results are not |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
502 # cached, so finding the size of every revision will be slower. |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
503 """ |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
504 if self.cache and self.cache[1] == rev: |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
505 return len(self.cache[2]) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
506 |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
507 base = self.base(rev) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
508 if self.cache and self.cache[1] >= base and self.cache[1] < rev: |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
509 base = self.cache[1] |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
510 text = self.cache[2] |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
511 else: |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
512 text = self.revision(self.node(base)) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
513 |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
514 l = len(text) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
515 for x in xrange(base + 1, rev + 1): |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
516 l = mdiff.patchedsize(l, self.chunk(x)) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
517 return l |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
518 """ |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
519 |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
520 def length(self, rev): |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
521 if rev < 0: |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
522 return 0 |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
523 else: |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
524 return self.index[rev][1] |
2072 | 525 def base(self, rev): return (rev < 0) and rev or self.index[rev][-5] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
526 |
1074
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
527 def reachable(self, rev, stop=None): |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
528 reachable = {} |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
529 visit = [rev] |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
530 reachable[rev] = 1 |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
531 if stop: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
532 stopn = self.rev(stop) |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
533 else: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
534 stopn = 0 |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
535 while visit: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
536 n = visit.pop(0) |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
537 if n == stop: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
538 continue |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
539 if n == nullid: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
540 continue |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
541 for p in self.parents(n): |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
542 if self.rev(p) < stopn: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
543 continue |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
544 if p not in reachable: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
545 reachable[p] = 1 |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
546 visit.append(p) |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
547 return reachable |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
548 |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
549 def nodesbetween(self, roots=None, heads=None): |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
550 """Return a tuple containing three elements. Elements 1 and 2 contain |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
551 a final list bases and heads after all the unreachable ones have been |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
552 pruned. Element 0 contains a topologically sorted list of all |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
553 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
554 nodes that satisfy these constraints: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
555 1. All nodes must be descended from a node in roots (the nodes on |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
556 roots are considered descended from themselves). |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
557 2. All nodes must also be ancestors of a node in heads (the nodes in |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
558 heads are considered to be their own ancestors). |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
559 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
560 If roots is unspecified, nullid is assumed as the only root. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
561 If heads is unspecified, it is taken to be the output of the |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
562 heads method (i.e. a list of all nodes in the repository that |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
563 have no children).""" |
1463
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
564 nonodes = ([], [], []) |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
565 if roots is not None: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
566 roots = list(roots) |
1463
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
567 if not roots: |
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
568 return nonodes |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
569 lowestrev = min([self.rev(n) for n in roots]) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
570 else: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
571 roots = [nullid] # Everybody's a descendent of nullid |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
572 lowestrev = -1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
573 if (lowestrev == -1) and (heads is None): |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
574 # We want _all_ the nodes! |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
575 return ([self.node(r) for r in xrange(0, self.count())], |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
576 [nullid], list(self.heads())) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
577 if heads is None: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
578 # All nodes are ancestors, so the latest ancestor is the last |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
579 # node. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
580 highestrev = self.count() - 1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
581 # Set ancestors to None to signal that every node is an ancestor. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
582 ancestors = None |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
583 # Set heads to an empty dictionary for later discovery of heads |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
584 heads = {} |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
585 else: |
1463
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
586 heads = list(heads) |
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
587 if not heads: |
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
588 return nonodes |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
589 ancestors = {} |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
590 # Start at the top and keep marking parents until we're done. |
1463
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
591 nodestotag = heads[:] |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
592 # Turn heads into a dictionary so we can remove 'fake' heads. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
593 # Also, later we will be using it to filter out the heads we can't |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
594 # find from roots. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
595 heads = dict.fromkeys(heads, 0) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
596 # Remember where the top was so we can use it as a limit later. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
597 highestrev = max([self.rev(n) for n in nodestotag]) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
598 while nodestotag: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
599 # grab a node to tag |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
600 n = nodestotag.pop() |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
601 # Never tag nullid |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
602 if n == nullid: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
603 continue |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
604 # A node's revision number represents its place in a |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
605 # topologically sorted list of nodes. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
606 r = self.rev(n) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
607 if r >= lowestrev: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
608 if n not in ancestors: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
609 # If we are possibly a descendent of one of the roots |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
610 # and we haven't already been marked as an ancestor |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
611 ancestors[n] = 1 # Mark as ancestor |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
612 # Add non-nullid parents to list of nodes to tag. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
613 nodestotag.extend([p for p in self.parents(n) if |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
614 p != nullid]) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
615 elif n in heads: # We've seen it before, is it a fake head? |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
616 # So it is, real heads should not be the ancestors of |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
617 # any other heads. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
618 heads.pop(n) |
1459
106fdec8e1fb
Fix small bug in nodesbetween if heads is [nullid].
Eric Hopper <hopper@omnifarious.org>
parents:
1458
diff
changeset
|
619 if not ancestors: |
1463
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
620 return nonodes |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
621 # Now that we have our set of ancestors, we want to remove any |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
622 # roots that are not ancestors. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
623 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
624 # If one of the roots was nullid, everything is included anyway. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
625 if lowestrev > -1: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
626 # But, since we weren't, let's recompute the lowest rev to not |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
627 # include roots that aren't ancestors. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
628 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
629 # Filter out roots that aren't ancestors of heads |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
630 roots = [n for n in roots if n in ancestors] |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
631 # Recompute the lowest revision |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
632 if roots: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
633 lowestrev = min([self.rev(n) for n in roots]) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
634 else: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
635 # No more roots? Return empty list |
1463
26e73acc0cdf
Fix to handle case of empty list for roots or heads in nodesbetween.
Eric Hopper <hopper@omnifarious.org>
parents:
1459
diff
changeset
|
636 return nonodes |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
637 else: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
638 # We are descending from nullid, and don't need to care about |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
639 # any other roots. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
640 lowestrev = -1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
641 roots = [nullid] |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
642 # Transform our roots list into a 'set' (i.e. a dictionary where the |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
643 # values don't matter. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
644 descendents = dict.fromkeys(roots, 1) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
645 # Also, keep the original roots so we can filter out roots that aren't |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
646 # 'real' roots (i.e. are descended from other roots). |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
647 roots = descendents.copy() |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
648 # Our topologically sorted list of output nodes. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
649 orderedout = [] |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
650 # Don't start at nullid since we don't want nullid in our output list, |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
651 # and if nullid shows up in descedents, empty parents will look like |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
652 # they're descendents. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
653 for r in xrange(max(lowestrev, 0), highestrev + 1): |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
654 n = self.node(r) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
655 isdescendent = False |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
656 if lowestrev == -1: # Everybody is a descendent of nullid |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
657 isdescendent = True |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
658 elif n in descendents: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
659 # n is already a descendent |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
660 isdescendent = True |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
661 # This check only needs to be done here because all the roots |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
662 # will start being marked is descendents before the loop. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
663 if n in roots: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
664 # If n was a root, check if it's a 'real' root. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
665 p = tuple(self.parents(n)) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
666 # If any of its parents are descendents, it's not a root. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
667 if (p[0] in descendents) or (p[1] in descendents): |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
668 roots.pop(n) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
669 else: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
670 p = tuple(self.parents(n)) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
671 # A node is a descendent if either of its parents are |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
672 # descendents. (We seeded the dependents list with the roots |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
673 # up there, remember?) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
674 if (p[0] in descendents) or (p[1] in descendents): |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
675 descendents[n] = 1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
676 isdescendent = True |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
677 if isdescendent and ((ancestors is None) or (n in ancestors)): |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
678 # Only include nodes that are both descendents and ancestors. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
679 orderedout.append(n) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
680 if (ancestors is not None) and (n in heads): |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
681 # We're trying to figure out which heads are reachable |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
682 # from roots. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
683 # Mark this head as having been reached |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
684 heads[n] = 1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
685 elif ancestors is None: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
686 # Otherwise, we're trying to discover the heads. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
687 # Assume this is a head because if it isn't, the next step |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
688 # will eventually remove it. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
689 heads[n] = 1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
690 # But, obviously its parents aren't. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
691 for p in self.parents(n): |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
692 heads.pop(p, None) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
693 heads = [n for n in heads.iterkeys() if heads[n] != 0] |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
694 roots = roots.keys() |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
695 assert orderedout |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
696 assert roots |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
697 assert heads |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
698 return (orderedout, roots, heads) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
699 |
1551
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
700 def heads(self, start=None): |
1550
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
701 """return the list of all nodes that have no children |
1551
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
702 |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
703 if start is specified, only heads that are descendants of |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
704 start will be returned |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
705 |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
706 """ |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
707 if start is None: |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
708 start = nullid |
1550
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
709 reachable = {start: 1} |
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
710 heads = {start: 1} |
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
711 startrev = self.rev(start) |
1083 | 712 |
1550
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
713 for r in xrange(startrev + 1, self.count()): |
221 | 714 n = self.node(r) |
715 for pn in self.parents(n): | |
1550
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
716 if pn in reachable: |
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
717 reachable[n] = 1 |
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
718 heads[n] = 1 |
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
719 if pn in heads: |
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
720 del heads[pn] |
ccb9b62de892
add a -r/--rev option to heads to show only heads descendant from rev
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1535
diff
changeset
|
721 return heads.keys() |
370 | 722 |
723 def children(self, node): | |
1083 | 724 """find the children of a given node""" |
370 | 725 c = [] |
726 p = self.rev(node) | |
727 for r in range(p + 1, self.count()): | |
728 n = self.node(r) | |
729 for pn in self.parents(n): | |
854
473c030d34a6
Fixed revlog.children.
Tristan Wibberley <tristan@wibberley.org>
parents:
655
diff
changeset
|
730 if pn == node: |
473c030d34a6
Fixed revlog.children.
Tristan Wibberley <tristan@wibberley.org>
parents:
655
diff
changeset
|
731 c.append(n) |
370 | 732 continue |
733 elif pn == nullid: | |
734 continue | |
735 return c | |
515 | 736 |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
737 def lookup(self, id): |
1083 | 738 """locate a node based on revision number or subset of hex nodeid""" |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
739 try: |
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
740 rev = int(id) |
469 | 741 if str(rev) != id: raise ValueError |
742 if rev < 0: rev = self.count() + rev | |
476
0a338d506268
Really _call_ method revlog.count in revlog.lookup()
Thomas Arendsen Hein <thomas@intevation.de>
parents:
469
diff
changeset
|
743 if rev < 0 or rev >= self.count(): raise ValueError |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
744 return self.node(rev) |
469 | 745 except (ValueError, OverflowError): |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
746 c = [] |
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
747 for n in self.nodemap: |
469 | 748 if hex(n).startswith(id): |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
749 c.append(n) |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
750 if len(c) > 1: raise RevlogError(_("Ambiguous identifier")) |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
751 if len(c) < 1: raise RevlogError(_("No match found")) |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
752 return c[0] |
515 | 753 |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
754 return None |
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
755 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
756 def diff(self, a, b): |
1083 | 757 """return a delta between two revisions""" |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
758 return mdiff.textdiff(a, b) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
759 |
73 | 760 def patches(self, t, pl): |
1083 | 761 """apply a list of patches to a string""" |
73 | 762 return mdiff.patches(t, pl) |
763 | |
2072 | 764 def chunk(self, rev, df=None, cachelen=4096): |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
765 start, length = self.start(rev), self.length(rev) |
2073 | 766 inline = self.inlinedata() |
767 if inline: | |
768 start += (rev + 1) * struct.calcsize(self.indexformat) | |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
769 end = start + length |
2072 | 770 def loadcache(df): |
771 cache_length = max(cachelen, length) # 4k | |
772 if not df: | |
2073 | 773 if inline: |
774 df = self.opener(self.indexfile) | |
775 else: | |
776 df = self.opener(self.datafile) | |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
777 df.seek(start) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
778 self.chunkcache = (start, df.read(cache_length)) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
779 |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
780 if not self.chunkcache: |
2072 | 781 loadcache(df) |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
782 |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
783 cache_start = self.chunkcache[0] |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
784 cache_end = cache_start + len(self.chunkcache[1]) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
785 if start >= cache_start and end <= cache_end: |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
786 # it is cached |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
787 offset = start - cache_start |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
788 else: |
2072 | 789 loadcache(df) |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
790 offset = 0 |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
791 |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
792 #def checkchunk(): |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
793 # df = self.opener(self.datafile) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
794 # df.seek(start) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
795 # return df.read(length) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
796 #assert s == checkchunk() |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
797 return decompress(self.chunkcache[1][offset:offset + length]) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
798 |
119
c7a66f9752a4
Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents:
117
diff
changeset
|
799 def delta(self, node): |
1083 | 800 """return or calculate a delta between a node and its predecessor""" |
119
c7a66f9752a4
Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents:
117
diff
changeset
|
801 r = self.rev(node) |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
802 return self.revdiff(r - 1, r) |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
803 |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
804 def revdiff(self, rev1, rev2): |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
805 """return or calculate a delta between two revisions""" |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
806 b1 = self.base(rev1) |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
807 b2 = self.base(rev2) |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
808 if b1 == b2 and rev1 + 1 == rev2: |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
809 return self.chunk(rev2) |
119
c7a66f9752a4
Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents:
117
diff
changeset
|
810 else: |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
811 return self.diff(self.revision(self.node(rev1)), |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
812 self.revision(self.node(rev2))) |
119
c7a66f9752a4
Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents:
117
diff
changeset
|
813 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
814 def revision(self, node): |
1083 | 815 """return an uncompressed revision of a given""" |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
816 if node == nullid: return "" |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
817 if self.cache and self.cache[0] == node: return self.cache[2] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
818 |
1083 | 819 # look up what we need to read |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
820 text = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
821 rev = self.rev(node) |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
822 base = self.base(rev) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
823 |
2073 | 824 if self.inlinedata(): |
825 # we probably have the whole chunk cached | |
826 df = None | |
827 else: | |
828 df = self.opener(self.datafile) | |
2072 | 829 |
1083 | 830 # do we have useful data cached? |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
831 if self.cache and self.cache[1] >= base and self.cache[1] < rev: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
832 base = self.cache[1] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
833 text = self.cache[2] |
2079 | 834 self.loadindex(base, rev + 1) |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
835 else: |
2079 | 836 self.loadindex(base, rev + 1) |
2072 | 837 text = self.chunk(base, df=df) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
838 |
71
47c9a869adee
Add mdiff.patches to speed up applying thousands of patches to the manifest
mpm@selenic.com
parents:
67
diff
changeset
|
839 bins = [] |
64 | 840 for r in xrange(base + 1, rev + 1): |
2072 | 841 bins.append(self.chunk(r, df=df)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
842 |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
843 text = self.patches(text, bins) |
71
47c9a869adee
Add mdiff.patches to speed up applying thousands of patches to the manifest
mpm@selenic.com
parents:
67
diff
changeset
|
844 |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
845 p1, p2 = self.parents(node) |
26 | 846 if node != hash(text, p1, p2): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
847 raise RevlogError(_("integrity check failed on %s:%d") |
98 | 848 % (self.datafile, rev)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
849 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
850 self.cache = (node, rev, text) |
515 | 851 return text |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
852 |
2075
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
853 def checkinlinesize(self, tr, fp=None): |
2073 | 854 if not self.inlinedata(): |
855 return | |
2075
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
856 if not fp: |
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
857 fp = self.opener(self.indexfile, 'r') |
2082
856f0ba200bc
Additional appendfile fixes for interleaved data/index files
mason@suse.com
parents:
2081
diff
changeset
|
858 fp.seek(0, 2) |
2073 | 859 size = fp.tell() |
860 if size < 131072: | |
861 return | |
2084 | 862 trinfo = tr.find(self.indexfile) |
863 if trinfo == None: | |
864 raise RevlogError(_("%s not found in the transaction" % | |
865 self.indexfile)) | |
866 | |
867 trindex = trinfo[2] | |
868 dataoff = self.start(trindex) | |
869 | |
870 tr.add(self.datafile, dataoff) | |
2073 | 871 df = self.opener(self.datafile, 'w') |
872 calc = struct.calcsize(self.indexformat) | |
873 for r in xrange(self.count()): | |
874 start = self.start(r) + (r + 1) * calc | |
875 length = self.length(r) | |
876 fp.seek(start) | |
877 d = fp.read(length) | |
878 df.write(d) | |
879 fp.close() | |
880 df.close() | |
2076
d007df6daf8e
Create an atomic opener that does not automatically rename on close
mason@suse.com
parents:
2075
diff
changeset
|
881 fp = self.opener(self.indexfile, 'w', atomictemp=True) |
2073 | 882 self.version &= ~(REVLOGNGINLINEDATA) |
883 if self.count(): | |
884 x = self.index[0] | |
885 e = struct.pack(self.indexformat, *x)[4:] | |
886 l = struct.pack(versionformat, self.version) | |
887 fp.write(l) | |
888 fp.write(e) | |
889 | |
890 for i in xrange(1, self.count()): | |
891 x = self.index[i] | |
892 e = struct.pack(self.indexformat, *x) | |
893 fp.write(e) | |
894 | |
2076
d007df6daf8e
Create an atomic opener that does not automatically rename on close
mason@suse.com
parents:
2075
diff
changeset
|
895 # if we don't call rename, the temp file will never replace the |
d007df6daf8e
Create an atomic opener that does not automatically rename on close
mason@suse.com
parents:
2075
diff
changeset
|
896 # real index |
d007df6daf8e
Create an atomic opener that does not automatically rename on close
mason@suse.com
parents:
2075
diff
changeset
|
897 fp.rename() |
2084 | 898 |
899 tr.replace(self.indexfile, trindex * calc) | |
2073 | 900 self.chunkcache = None |
901 | |
644 | 902 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None): |
1083 | 903 """add a revision to the log |
904 | |
905 text - the revision data to add | |
906 transaction - the transaction object used for rollback | |
907 link - the linkrev data to add | |
908 p1, p2 - the parent nodeids of the revision | |
909 d - an optional precomputed delta | |
910 """ | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
911 if text is None: text = "" |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
912 if p1 is None: p1 = self.tip() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
913 if p2 is None: p2 = nullid |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
914 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
915 node = hash(text, p1, p2) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
916 |
301 | 917 if node in self.nodemap: |
918 return node | |
919 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
920 n = self.count() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
921 t = n - 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
922 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
923 if n: |
64 | 924 base = self.base(t) |
925 start = self.start(base) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
926 end = self.end(t) |
644 | 927 if not d: |
928 prev = self.revision(self.tip()) | |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
929 d = self.diff(prev, str(text)) |
98 | 930 data = compress(d) |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
931 l = len(data[1]) + len(data[0]) |
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
932 dist = end - start + l |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
933 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
934 # full versions are inserted when the needed deltas |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
935 # become comparable to the uncompressed text |
64 | 936 if not n or dist > len(text) * 2: |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
937 data = compress(text) |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
938 l = len(data[1]) + len(data[0]) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
939 base = n |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
940 else: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
941 base = self.base(t) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
942 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
943 offset = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
944 if t >= 0: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
945 offset = self.end(t) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
946 |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
947 if self.version == REVLOGV0: |
2072 | 948 e = (offset, l, base, link, p1, p2, node) |
949 else: | |
950 e = (self.offset_type(offset, 0), l, len(text), | |
951 base, link, self.rev(p1), self.rev(p2), node) | |
515 | 952 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
953 self.index.append(e) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
954 self.nodemap[node] = n |
2072 | 955 entry = struct.pack(self.indexformat, *e) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
956 |
2073 | 957 if not self.inlinedata(): |
958 transaction.add(self.datafile, offset) | |
959 transaction.add(self.indexfile, n * len(entry)) | |
960 f = self.opener(self.datafile, "a") | |
961 if data[0]: | |
962 f.write(data[0]) | |
963 f.write(data[1]) | |
2089
cb99c711c59f
make appendfile simpler so it does not break with revlogng on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2084
diff
changeset
|
964 f.close() |
2073 | 965 f = self.opener(self.indexfile, "a") |
966 else: | |
967 f = self.opener(self.indexfile, "a+") | |
2077
4d0700ae0991
Fix inlined revlogs to seek to eof after opening "a+"
mason@suse.com
parents:
2076
diff
changeset
|
968 f.seek(0, 2) |
2084 | 969 transaction.add(self.indexfile, f.tell(), self.count() - 1) |
2072 | 970 |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
971 if len(self.index) == 1 and self.version != REVLOGV0: |
2072 | 972 l = struct.pack(versionformat, self.version) |
973 f.write(l) | |
974 entry = entry[4:] | |
975 | |
976 f.write(entry) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
977 |
2073 | 978 if self.inlinedata(): |
979 f.write(data[0]) | |
980 f.write(data[1]) | |
2075
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
981 self.checkinlinesize(transaction, f) |
2073 | 982 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
983 self.cache = (node, n, text) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
984 return node |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
985 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
986 def ancestor(self, a, b): |
1083 | 987 """calculate the least common ancestor of nodes a and b""" |
2081
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
988 |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
989 # start with some short cuts for the linear cases |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
990 if a == b: |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
991 return a |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
992 ra = self.rev(a) |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
993 rb = self.rev(b) |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
994 if ra < rb: |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
995 last = b |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
996 first = a |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
997 else: |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
998 last = a |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
999 first = b |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1000 |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1001 # reachable won't include stop in the list, so we have to use a parent |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1002 reachable = self.reachable(last, stop=self.parents(first)[0]) |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1003 if first in reachable: |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1004 return first |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1005 |
147 | 1006 # calculate the distance of every node from root |
1007 dist = {nullid: 0} | |
1008 for i in xrange(self.count()): | |
1009 n = self.node(i) | |
1010 p1, p2 = self.parents(n) | |
1011 dist[n] = max(dist[p1], dist[p2]) + 1 | |
515 | 1012 |
147 | 1013 # traverse ancestors in order of decreasing distance from root |
1014 def ancestors(node): | |
1015 # we store negative distances because heap returns smallest member | |
1016 h = [(-dist[node], node)] | |
1017 seen = {} | |
1018 while h: | |
1019 d, n = heapq.heappop(h) | |
1020 if n not in seen: | |
1021 seen[n] = 1 | |
1351
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1022 yield (-d, n) |
147 | 1023 for p in self.parents(n): |
1024 heapq.heappush(h, (-dist[p], p)) | |
45
f2b2d5daec30
Fix recursion depth trouble with ancestor algorithm
mpm@selenic.com
parents:
41
diff
changeset
|
1025 |
1351
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1026 def generations(node): |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1027 sg, s = None, {} |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1028 for g,n in ancestors(node): |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1029 if g != sg: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1030 if sg: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1031 yield sg, s |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1032 sg, s = g, {n:1} |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1033 else: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1034 s[n] = 1 |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1035 yield sg, s |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1036 |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1037 x = generations(a) |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1038 y = generations(b) |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1039 gx = x.next() |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1040 gy = y.next() |
45
f2b2d5daec30
Fix recursion depth trouble with ancestor algorithm
mpm@selenic.com
parents:
41
diff
changeset
|
1041 |
147 | 1042 # increment each ancestor list until it is closer to root than |
1043 # the other, or they match | |
1044 while 1: | |
1351
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1045 #print "ancestor gen %s %s" % (gx[0], gy[0]) |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1046 if gx[0] == gy[0]: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1047 # find the intersection |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1048 i = [ n for n in gx[1] if n in gy[1] ] |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1049 if i: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1050 return i[0] |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1051 else: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1052 #print "next" |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1053 gy = y.next() |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1054 gx = x.next() |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1055 elif gx[0] < gy[0]: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1056 #print "next y" |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1057 gy = y.next() |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1058 else: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1059 #print "next x" |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1060 gx = x.next() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1061 |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
1062 def group(self, nodelist, lookup, infocollect=None): |
1083 | 1063 """calculate a delta group |
46 | 1064 |
1083 | 1065 Given a list of changeset revs, return a set of deltas and |
1066 metadata corresponding to nodes. the first delta is | |
1067 parent(nodes[0]) -> nodes[0] the receiver is guaranteed to | |
1068 have this parent as it has all history before these | |
1069 changesets. parent is parent[0] | |
1070 """ | |
1458
1033892bbb87
This changes the revlog.group and re-implements the localrepo.changeroup
Eric Hopper <hopper@omnifarious.org>
parents:
1457
diff
changeset
|
1071 revs = [self.rev(n) for n in nodelist] |
46 | 1072 |
1073 # if we don't have any revisions touched by these changesets, bail | |
192 | 1074 if not revs: |
1981
736b6c96bbbc
make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1941
diff
changeset
|
1075 yield changegroup.closechunk() |
192 | 1076 return |
46 | 1077 |
1078 # add the parent of the first rev | |
1079 p = self.parents(self.node(revs[0]))[0] | |
1080 revs.insert(0, self.rev(p)) | |
1081 | |
1082 # build deltas | |
71
47c9a869adee
Add mdiff.patches to speed up applying thousands of patches to the manifest
mpm@selenic.com
parents:
67
diff
changeset
|
1083 for d in xrange(0, len(revs) - 1): |
46 | 1084 a, b = revs[d], revs[d + 1] |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
1085 nb = self.node(b) |
192 | 1086 |
1458
1033892bbb87
This changes the revlog.group and re-implements the localrepo.changeroup
Eric Hopper <hopper@omnifarious.org>
parents:
1457
diff
changeset
|
1087 if infocollect is not None: |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
1088 infocollect(nb) |
1458
1033892bbb87
This changes the revlog.group and re-implements the localrepo.changeroup
Eric Hopper <hopper@omnifarious.org>
parents:
1457
diff
changeset
|
1089 |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
1090 d = self.revdiff(a, b) |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
1091 p = self.parents(nb) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
1092 meta = nb + p[0] + p[1] + lookup(nb) |
1981
736b6c96bbbc
make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1941
diff
changeset
|
1093 yield changegroup.genchunk("%s%s" % (meta, d)) |
46 | 1094 |
1981
736b6c96bbbc
make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1941
diff
changeset
|
1095 yield changegroup.closechunk() |
192 | 1096 |
1062 | 1097 def addgroup(self, revs, linkmapper, transaction, unique=0): |
1083 | 1098 """ |
1099 add a delta group | |
46 | 1100 |
1083 | 1101 given a set of deltas, add them to the revision log. the |
1102 first delta is against its parent, which should be in our | |
1103 log, the rest are against the previous delta. | |
1104 """ | |
1105 | |
1106 #track the base of the current delta log | |
46 | 1107 r = self.count() |
1108 t = r - 1 | |
2002
4aab906517c6
Calling revlog.addgroup with an empty changegroup now raises RevlogError.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1981
diff
changeset
|
1109 node = None |
515 | 1110 |
655 | 1111 base = prev = -1 |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1112 start = end = textlen = 0 |
46 | 1113 if r: |
1114 end = self.end(t) | |
1115 | |
2072 | 1116 ifh = self.opener(self.indexfile, "a+") |
2077
4d0700ae0991
Fix inlined revlogs to seek to eof after opening "a+"
mason@suse.com
parents:
2076
diff
changeset
|
1117 ifh.seek(0, 2) |
2084 | 1118 transaction.add(self.indexfile, ifh.tell(), self.count()) |
2073 | 1119 if self.inlinedata(): |
1120 dfh = None | |
1121 else: | |
1122 transaction.add(self.datafile, end) | |
1123 dfh = self.opener(self.datafile, "a") | |
46 | 1124 |
1125 # loop through our set of deltas | |
192 | 1126 chain = None |
1127 for chunk in revs: | |
1128 node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80]) | |
94 | 1129 link = linkmapper(cs) |
77 | 1130 if node in self.nodemap: |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
221
diff
changeset
|
1131 # this can happen if two branches make the same change |
1218
cde6818e082a
Add preliminary support for the bundle and unbundle commands
mpm@selenic.com
parents:
1214
diff
changeset
|
1132 # if unique: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1133 # raise RevlogError(_("already have %s") % hex(node[:4])) |
653
94cdd02792b5
Fix corruption resulting from skipping parts of a revision group
Matt Mackall <mpm@selenic.com>
parents:
651
diff
changeset
|
1134 chain = node |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
221
diff
changeset
|
1135 continue |
192 | 1136 delta = chunk[80:] |
1137 | |
1509
46a07392cf28
Add safety check for addgroup
Matt Mackall <mpm@selenic.com>
parents:
1494
diff
changeset
|
1138 for p in (p1, p2): |
46a07392cf28
Add safety check for addgroup
Matt Mackall <mpm@selenic.com>
parents:
1494
diff
changeset
|
1139 if not p in self.nodemap: |
46a07392cf28
Add safety check for addgroup
Matt Mackall <mpm@selenic.com>
parents:
1494
diff
changeset
|
1140 raise RevlogError(_("unknown parent %s") % short(p1)) |
46a07392cf28
Add safety check for addgroup
Matt Mackall <mpm@selenic.com>
parents:
1494
diff
changeset
|
1141 |
192 | 1142 if not chain: |
1143 # retrieve the parent revision of the delta chain | |
1144 chain = p1 | |
1145 if not chain in self.nodemap: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1146 raise RevlogError(_("unknown base %s") % short(chain[:4])) |
46 | 1147 |
1148 # full versions are inserted when the needed deltas become | |
1149 # comparable to the uncompressed text or when the previous | |
1150 # version is not the one we have a delta against. We use | |
1151 # the size of the previous full rev as a proxy for the | |
1152 # current size. | |
1153 | |
1154 if chain == prev: | |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
1155 tempd = compress(delta) |
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
1156 cdelta = tempd[0] + tempd[1] |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1157 textlen = mdiff.patchedsize(textlen, delta) |
46 | 1158 |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1159 if chain != prev or (end - start + len(cdelta)) > textlen * 2: |
46 | 1160 # flush our writes here so we can read it in revision |
2072 | 1161 if dfh: |
1162 dfh.flush() | |
46 | 1163 ifh.flush() |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1164 text = self.revision(chain) |
73 | 1165 text = self.patches(text, [delta]) |
46 | 1166 chk = self.addrevision(text, transaction, link, p1, p2) |
1167 if chk != node: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1168 raise RevlogError(_("consistency error adding group")) |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1169 textlen = len(text) |
46 | 1170 else: |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
1171 if self.version == REVLOGV0: |
2072 | 1172 e = (end, len(cdelta), base, link, p1, p2, node) |
1173 else: | |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1174 e = (self.offset_type(end, 0), len(cdelta), textlen, base, |
2072 | 1175 link, self.rev(p1), self.rev(p2), node) |
46 | 1176 self.index.append(e) |
1177 self.nodemap[node] = r | |
2073 | 1178 if self.inlinedata(): |
1179 ifh.write(struct.pack(self.indexformat, *e)) | |
1180 ifh.write(cdelta) | |
2075
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
1181 self.checkinlinesize(transaction, ifh) |
2073 | 1182 if not self.inlinedata(): |
1183 dfh = self.opener(self.datafile, "a") | |
1184 ifh = self.opener(self.indexfile, "a") | |
1185 else: | |
1186 if not dfh: | |
1187 # addrevision switched from inline to conventional | |
1188 # reopen the index | |
1189 dfh = self.opener(self.datafile, "a") | |
1190 ifh = self.opener(self.indexfile, "a") | |
1191 dfh.write(cdelta) | |
1192 ifh.write(struct.pack(self.indexformat, *e)) | |
46 | 1193 |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1194 t, r, chain, prev = r, r + 1, node, node |
1749
d457fec76ab0
fix warnings from pychecker (unused variables and shadowing)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1711
diff
changeset
|
1195 base = self.base(t) |
d457fec76ab0
fix warnings from pychecker (unused variables and shadowing)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1711
diff
changeset
|
1196 start = self.start(base) |
46 | 1197 end = self.end(t) |
1198 | |
2002
4aab906517c6
Calling revlog.addgroup with an empty changegroup now raises RevlogError.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1981
diff
changeset
|
1199 if node is None: |
4aab906517c6
Calling revlog.addgroup with an empty changegroup now raises RevlogError.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1981
diff
changeset
|
1200 raise RevlogError(_("group to be added is empty")) |
46 | 1201 return node |
1493
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1202 |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1203 def strip(self, rev, minlink): |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1204 if self.count() == 0 or rev >= self.count(): |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1205 return |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1206 |
2072 | 1207 if isinstance(self.index, lazyindex): |
1208 self.loadindexmap() | |
1209 | |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1210 # When stripping away a revision, we need to make sure it |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1211 # does not actually belong to an older changeset. |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1212 # The minlink parameter defines the oldest revision |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1213 # we're allowed to strip away. |
2072 | 1214 while minlink > self.index[rev][-4]: |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1215 rev += 1 |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1216 if rev >= self.count(): |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1217 return |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1218 |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1219 # first truncate the files on disk |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1220 end = self.start(rev) |
2073 | 1221 if not self.inlinedata(): |
1222 df = self.opener(self.datafile, "a") | |
1223 df.truncate(end) | |
1224 end = rev * struct.calcsize(self.indexformat) | |
1225 else: | |
1226 end += rev * struct.calcsize(self.indexformat) | |
2072 | 1227 |
1228 indexf = self.opener(self.indexfile, "a") | |
1229 indexf.truncate(end) | |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1230 |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1231 # then reset internal state in memory to forget those revisions |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1232 self.cache = None |
1711 | 1233 self.chunkcache = None |
2072 | 1234 for x in xrange(rev, self.count()): |
1235 del self.nodemap[self.node(x)] | |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1236 |
2072 | 1237 del self.index[rev:] |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1238 |
1493
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1239 def checksize(self): |
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1240 expected = 0 |
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1241 if self.count(): |
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1242 expected = self.end(self.count() - 1) |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1243 |
1494
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1244 try: |
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1245 f = self.opener(self.datafile) |
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1246 f.seek(0, 2) |
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1247 actual = f.tell() |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1248 dd = actual - expected |
1494
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1249 except IOError, inst: |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1250 if inst.errno != errno.ENOENT: |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1251 raise |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1252 dd = 0 |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1253 |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1254 try: |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1255 f = self.opener(self.indexfile) |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1256 f.seek(0, 2) |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1257 actual = f.tell() |
2072 | 1258 s = struct.calcsize(self.indexformat) |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1259 i = actual / s |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1260 di = actual - (i * s) |
2073 | 1261 if self.inlinedata(): |
1262 databytes = 0 | |
1263 for r in xrange(self.count()): | |
1264 databytes += self.length(r) | |
1265 dd = 0 | |
1266 di = actual - self.count() * s - databytes | |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1267 except IOError, inst: |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1268 if inst.errno != errno.ENOENT: |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1269 raise |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1270 di = 0 |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1271 |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1272 return (dd, di) |
1494
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1273 |
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1274 |