Mercurial > hg > mercurial-crew-with-dirclash
annotate mercurial/revlog.py @ 2569:2264b2b077a1
run-tests.py: make tests use same python interpreter as test harness.
this is wanted because some tests run python interpreter directly.
must use same python interpreter in tests as in main harness or problems
will happen because of e.g. different python abi if run-tests.py run
with python 2.5 but system python is 2.4.
fix is to see if system python is used and is named python. if no,
put symlink called python at front of shell search path.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Thu, 06 Jul 2006 10:09:24 -0700 |
parents | 494f7787d8ee |
children | c4325f0a9b91 |
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 ] | |
2489
568e58eed096
Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2354
diff
changeset
|
480 def parentrevs(self, rev): |
568e58eed096
Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2354
diff
changeset
|
481 if rev == -1: |
568e58eed096
Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2354
diff
changeset
|
482 return (-1, -1) |
568e58eed096
Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2354
diff
changeset
|
483 d = self.index[rev][-3:-1] |
568e58eed096
Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2354
diff
changeset
|
484 if self.version == REVLOGV0: |
568e58eed096
Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2354
diff
changeset
|
485 return [ self.rev(x) for x in d ] |
568e58eed096
Add revlog.parentrevs function.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2354
diff
changeset
|
486 return d |
2072 | 487 def start(self, rev): |
488 if rev < 0: | |
489 return -1 | |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
490 if self.version != REVLOGV0: |
2072 | 491 return self.ngoffset(self.index[rev][0]) |
492 return self.index[rev][0] | |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
493 |
2072 | 494 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
|
495 |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
496 def size(self, rev): |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
497 """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
|
498 l = -1 |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
499 if self.version != REVLOGV0: |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
500 l = self.index[rev][2] |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
501 if l >= 0: |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
502 return l |
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 t = self.revision(self.node(rev)) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
505 return len(t) |
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 # 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
|
508 # 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
|
509 # 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
|
510 """ |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
511 if self.cache and self.cache[1] == rev: |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
512 return len(self.cache[2]) |
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 base = self.base(rev) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
515 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
|
516 base = self.cache[1] |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
517 text = self.cache[2] |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
518 else: |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
519 text = self.revision(self.node(base)) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
520 |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
521 l = len(text) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
522 for x in xrange(base + 1, rev + 1): |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
523 l = mdiff.patchedsize(l, self.chunk(x)) |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
524 return l |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
525 """ |
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
526 |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
527 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
|
528 if rev < 0: |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
529 return 0 |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
530 else: |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
531 return self.index[rev][1] |
2072 | 532 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
|
533 |
1074
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
534 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
|
535 reachable = {} |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
536 visit = [rev] |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
537 reachable[rev] = 1 |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
538 if stop: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
539 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
|
540 else: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
541 stopn = 0 |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
542 while visit: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
543 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
|
544 if n == stop: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
545 continue |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
546 if n == nullid: |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
547 continue |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
548 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
|
549 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
|
550 continue |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
551 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
|
552 reachable[p] = 1 |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
553 visit.append(p) |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
554 return reachable |
55bf5cfde69e
Add revlog.reachable to find a graph of ancestors for a given rev
mason@suse.com
parents:
1073
diff
changeset
|
555 |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
556 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
|
557 """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
|
558 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
|
559 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
|
560 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
561 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
|
562 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
|
563 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
|
564 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
|
565 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
|
566 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
567 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
|
568 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
|
569 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
|
570 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
|
571 nonodes = ([], [], []) |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
572 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
|
573 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
|
574 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
|
575 return nonodes |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
576 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
|
577 else: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
578 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
|
579 lowestrev = -1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
580 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
|
581 # 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
|
582 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
|
583 [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
|
584 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
|
585 # 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
|
586 # node. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
587 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
|
588 # 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
|
589 ancestors = None |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
590 # 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
|
591 heads = {} |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
592 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
|
593 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
|
594 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
|
595 return nonodes |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
596 ancestors = {} |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
597 # 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
|
598 nodestotag = heads[:] |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
599 # 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
|
600 # 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
|
601 # find from roots. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
602 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
|
603 # 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
|
604 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
|
605 while nodestotag: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
606 # 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
|
607 n = nodestotag.pop() |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
608 # Never tag nullid |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
609 if n == nullid: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
610 continue |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
611 # 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
|
612 # 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
|
613 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
|
614 if r >= lowestrev: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
615 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
|
616 # 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
|
617 # 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
|
618 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
|
619 # 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
|
620 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
|
621 p != nullid]) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
622 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
|
623 # 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
|
624 # any other heads. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
625 heads.pop(n) |
1459
106fdec8e1fb
Fix small bug in nodesbetween if heads is [nullid].
Eric Hopper <hopper@omnifarious.org>
parents:
1458
diff
changeset
|
626 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
|
627 return nonodes |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
628 # 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
|
629 # 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
|
630 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
631 # 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
|
632 if lowestrev > -1: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
633 # 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
|
634 # 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
|
635 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
636 # 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
|
637 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
|
638 # 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
|
639 if roots: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
640 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
|
641 else: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
642 # 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
|
643 return nonodes |
1457
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
644 else: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
645 # 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
|
646 # any other roots. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
647 lowestrev = -1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
648 roots = [nullid] |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
649 # 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
|
650 # 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
|
651 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
|
652 # 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
|
653 # '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
|
654 roots = descendents.copy() |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
655 # 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
|
656 orderedout = [] |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
657 # 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
|
658 # 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
|
659 # they're descendents. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
660 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
|
661 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
|
662 isdescendent = False |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
663 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
|
664 isdescendent = True |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
665 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
|
666 # 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
|
667 isdescendent = True |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
668 # 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
|
669 # 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
|
670 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
|
671 # 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
|
672 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
|
673 # 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
|
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 roots.pop(n) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
676 else: |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
677 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
|
678 # 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
|
679 # 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
|
680 # up there, remember?) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
681 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
|
682 descendents[n] = 1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
683 isdescendent = True |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
684 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
|
685 # 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
|
686 orderedout.append(n) |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
687 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
|
688 # 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
|
689 # from roots. |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
690 # 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
|
691 heads[n] = 1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
692 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
|
693 # 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
|
694 # 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
|
695 # 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
|
696 heads[n] = 1 |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
697 # 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
|
698 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
|
699 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
|
700 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
|
701 roots = roots.keys() |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
702 assert orderedout |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
703 assert roots |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
704 assert heads |
518da3c3b6ce
This implements the nodesbetween method, and it removes the newer method
Eric Hopper <hopper@omnifarious.org>
parents:
1351
diff
changeset
|
705 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
|
706 |
1551
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
707 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
|
708 """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
|
709 |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
710 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
|
711 start will be returned |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
712 |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
713 """ |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
714 if start is None: |
e793cbc8be00
Fixes to "hg heads -r FOO":
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1550
diff
changeset
|
715 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
|
716 startrev = self.rev(start) |
2490
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
717 reachable = {startrev: 1} |
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
718 heads = {startrev: 1} |
1083 | 719 |
2490
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
720 parentrevs = self.parentrevs |
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
|
721 for r in xrange(startrev + 1, self.count()): |
2490
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
722 for p in parentrevs(r): |
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
723 if p in reachable: |
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
724 reachable[r] = 1 |
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
725 heads[r] = 1 |
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
726 if p in heads: |
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
727 del heads[p] |
6ff82ec1f4b8
Change revlog.heads to walk the revision graph using revision numbers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
2489
diff
changeset
|
728 return [self.node(r) for r in heads] |
370 | 729 |
730 def children(self, node): | |
1083 | 731 """find the children of a given node""" |
370 | 732 c = [] |
733 p = self.rev(node) | |
734 for r in range(p + 1, self.count()): | |
735 n = self.node(r) | |
736 for pn in self.parents(n): | |
854
473c030d34a6
Fixed revlog.children.
Tristan Wibberley <tristan@wibberley.org>
parents:
655
diff
changeset
|
737 if pn == node: |
473c030d34a6
Fixed revlog.children.
Tristan Wibberley <tristan@wibberley.org>
parents:
655
diff
changeset
|
738 c.append(n) |
370 | 739 continue |
740 elif pn == nullid: | |
741 continue | |
742 return c | |
515 | 743 |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
744 def lookup(self, id): |
1083 | 745 """locate a node based on revision number or subset of hex nodeid""" |
2561
494f7787d8ee
revlog: make lookup handle binary nodes
Matt Mackall <mpm@selenic.com>
parents:
2560
diff
changeset
|
746 if id in self.nodemap: |
494f7787d8ee
revlog: make lookup handle binary nodes
Matt Mackall <mpm@selenic.com>
parents:
2560
diff
changeset
|
747 return id |
2560
c35694df7b13
revlog: handle integer arguments to lookup
Matt Mackall <mpm@selenic.com>
parents:
2490
diff
changeset
|
748 if type(id) == type(0): |
c35694df7b13
revlog: handle integer arguments to lookup
Matt Mackall <mpm@selenic.com>
parents:
2490
diff
changeset
|
749 rev = id |
c35694df7b13
revlog: handle integer arguments to lookup
Matt Mackall <mpm@selenic.com>
parents:
2490
diff
changeset
|
750 if rev < 0: rev = self.count() + rev |
c35694df7b13
revlog: handle integer arguments to lookup
Matt Mackall <mpm@selenic.com>
parents:
2490
diff
changeset
|
751 if rev < 0 or rev >= self.count(): return None |
c35694df7b13
revlog: handle integer arguments to lookup
Matt Mackall <mpm@selenic.com>
parents:
2490
diff
changeset
|
752 return self.node(rev) |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
753 try: |
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
754 rev = int(id) |
469 | 755 if str(rev) != id: raise ValueError |
756 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
|
757 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
|
758 return self.node(rev) |
469 | 759 except (ValueError, OverflowError): |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
760 c = [] |
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
761 for n in self.nodemap: |
469 | 762 if hex(n).startswith(id): |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
763 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
|
764 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
|
765 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
|
766 return c[0] |
515 | 767 |
36
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
768 return None |
da28286bf6b7
Add smart node lookup by substring or by rev number
mpm@selenic.com
parents:
26
diff
changeset
|
769 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
770 def diff(self, a, b): |
1083 | 771 """return a delta between two revisions""" |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
772 return mdiff.textdiff(a, b) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
773 |
73 | 774 def patches(self, t, pl): |
1083 | 775 """apply a list of patches to a string""" |
73 | 776 return mdiff.patches(t, pl) |
777 | |
2072 | 778 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
|
779 start, length = self.start(rev), self.length(rev) |
2073 | 780 inline = self.inlinedata() |
781 if inline: | |
782 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
|
783 end = start + length |
2072 | 784 def loadcache(df): |
785 cache_length = max(cachelen, length) # 4k | |
786 if not df: | |
2073 | 787 if inline: |
788 df = self.opener(self.indexfile) | |
789 else: | |
790 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
|
791 df.seek(start) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
792 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
|
793 |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
794 if not self.chunkcache: |
2072 | 795 loadcache(df) |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
796 |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
797 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
|
798 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
|
799 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
|
800 # it is cached |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
801 offset = start - cache_start |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
802 else: |
2072 | 803 loadcache(df) |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
804 offset = 0 |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
805 |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
806 #def checkchunk(): |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
807 # 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
|
808 # df.seek(start) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
809 # return df.read(length) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
810 #assert s == checkchunk() |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
811 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
|
812 |
119
c7a66f9752a4
Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents:
117
diff
changeset
|
813 def delta(self, node): |
1083 | 814 """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
|
815 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
|
816 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
|
817 |
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
818 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
|
819 """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
|
820 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
|
821 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
|
822 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
|
823 return self.chunk(rev2) |
119
c7a66f9752a4
Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents:
117
diff
changeset
|
824 else: |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
825 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
|
826 self.revision(self.node(rev2))) |
119
c7a66f9752a4
Add code to retrieve or construct a revlog delta
mpm@selenic.com
parents:
117
diff
changeset
|
827 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
828 def revision(self, node): |
1083 | 829 """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
|
830 if node == nullid: return "" |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
831 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
|
832 |
1083 | 833 # look up what we need to read |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
834 text = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
835 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
|
836 base = self.base(rev) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
837 |
2073 | 838 if self.inlinedata(): |
839 # we probably have the whole chunk cached | |
840 df = None | |
841 else: | |
842 df = self.opener(self.datafile) | |
2072 | 843 |
1083 | 844 # do we have useful data cached? |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
845 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
|
846 base = self.cache[1] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
847 text = self.cache[2] |
2079 | 848 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
|
849 else: |
2079 | 850 self.loadindex(base, rev + 1) |
2072 | 851 text = self.chunk(base, df=df) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
852 |
71
47c9a869adee
Add mdiff.patches to speed up applying thousands of patches to the manifest
mpm@selenic.com
parents:
67
diff
changeset
|
853 bins = [] |
64 | 854 for r in xrange(base + 1, rev + 1): |
2072 | 855 bins.append(self.chunk(r, df=df)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
856 |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
857 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
|
858 |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
859 p1, p2 = self.parents(node) |
26 | 860 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
|
861 raise RevlogError(_("integrity check failed on %s:%d") |
98 | 862 % (self.datafile, rev)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
863 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
864 self.cache = (node, rev, text) |
515 | 865 return text |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
866 |
2075
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
867 def checkinlinesize(self, tr, fp=None): |
2073 | 868 if not self.inlinedata(): |
869 return | |
2075
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
870 if not fp: |
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
871 fp = self.opener(self.indexfile, 'r') |
2082
856f0ba200bc
Additional appendfile fixes for interleaved data/index files
mason@suse.com
parents:
2081
diff
changeset
|
872 fp.seek(0, 2) |
2073 | 873 size = fp.tell() |
874 if size < 131072: | |
875 return | |
2084 | 876 trinfo = tr.find(self.indexfile) |
877 if trinfo == None: | |
878 raise RevlogError(_("%s not found in the transaction" % | |
879 self.indexfile)) | |
880 | |
881 trindex = trinfo[2] | |
882 dataoff = self.start(trindex) | |
883 | |
884 tr.add(self.datafile, dataoff) | |
2073 | 885 df = self.opener(self.datafile, 'w') |
886 calc = struct.calcsize(self.indexformat) | |
887 for r in xrange(self.count()): | |
888 start = self.start(r) + (r + 1) * calc | |
889 length = self.length(r) | |
890 fp.seek(start) | |
891 d = fp.read(length) | |
892 df.write(d) | |
893 fp.close() | |
894 df.close() | |
2076
d007df6daf8e
Create an atomic opener that does not automatically rename on close
mason@suse.com
parents:
2075
diff
changeset
|
895 fp = self.opener(self.indexfile, 'w', atomictemp=True) |
2073 | 896 self.version &= ~(REVLOGNGINLINEDATA) |
897 if self.count(): | |
898 x = self.index[0] | |
899 e = struct.pack(self.indexformat, *x)[4:] | |
900 l = struct.pack(versionformat, self.version) | |
901 fp.write(l) | |
902 fp.write(e) | |
903 | |
904 for i in xrange(1, self.count()): | |
905 x = self.index[i] | |
906 e = struct.pack(self.indexformat, *x) | |
907 fp.write(e) | |
908 | |
2076
d007df6daf8e
Create an atomic opener that does not automatically rename on close
mason@suse.com
parents:
2075
diff
changeset
|
909 # 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
|
910 # real index |
d007df6daf8e
Create an atomic opener that does not automatically rename on close
mason@suse.com
parents:
2075
diff
changeset
|
911 fp.rename() |
2084 | 912 |
913 tr.replace(self.indexfile, trindex * calc) | |
2073 | 914 self.chunkcache = None |
915 | |
644 | 916 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None): |
1083 | 917 """add a revision to the log |
918 | |
919 text - the revision data to add | |
920 transaction - the transaction object used for rollback | |
921 link - the linkrev data to add | |
922 p1, p2 - the parent nodeids of the revision | |
923 d - an optional precomputed delta | |
924 """ | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
925 if text is None: text = "" |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
926 if p1 is None: p1 = self.tip() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
927 if p2 is None: p2 = nullid |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
928 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
929 node = hash(text, p1, p2) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
930 |
301 | 931 if node in self.nodemap: |
932 return node | |
933 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
934 n = self.count() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
935 t = n - 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
936 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
937 if n: |
64 | 938 base = self.base(t) |
939 start = self.start(base) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
940 end = self.end(t) |
644 | 941 if not d: |
942 prev = self.revision(self.tip()) | |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
943 d = self.diff(prev, str(text)) |
98 | 944 data = compress(d) |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
945 l = len(data[1]) + len(data[0]) |
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
946 dist = end - start + l |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
947 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
948 # full versions are inserted when the needed deltas |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
949 # become comparable to the uncompressed text |
64 | 950 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
|
951 data = compress(text) |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
952 l = len(data[1]) + len(data[0]) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
953 base = n |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
954 else: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
955 base = self.base(t) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
956 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
957 offset = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
958 if t >= 0: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
959 offset = self.end(t) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
960 |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
961 if self.version == REVLOGV0: |
2072 | 962 e = (offset, l, base, link, p1, p2, node) |
963 else: | |
964 e = (self.offset_type(offset, 0), l, len(text), | |
965 base, link, self.rev(p1), self.rev(p2), node) | |
515 | 966 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
967 self.index.append(e) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
968 self.nodemap[node] = n |
2072 | 969 entry = struct.pack(self.indexformat, *e) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
970 |
2073 | 971 if not self.inlinedata(): |
972 transaction.add(self.datafile, offset) | |
973 transaction.add(self.indexfile, n * len(entry)) | |
974 f = self.opener(self.datafile, "a") | |
975 if data[0]: | |
976 f.write(data[0]) | |
977 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
|
978 f.close() |
2073 | 979 f = self.opener(self.indexfile, "a") |
980 else: | |
981 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
|
982 f.seek(0, 2) |
2084 | 983 transaction.add(self.indexfile, f.tell(), self.count() - 1) |
2072 | 984 |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
985 if len(self.index) == 1 and self.version != REVLOGV0: |
2072 | 986 l = struct.pack(versionformat, self.version) |
987 f.write(l) | |
988 entry = entry[4:] | |
989 | |
990 f.write(entry) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
991 |
2073 | 992 if self.inlinedata(): |
993 f.write(data[0]) | |
994 f.write(data[1]) | |
2075
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
995 self.checkinlinesize(transaction, f) |
2073 | 996 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
997 self.cache = (node, n, text) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
998 return node |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
999 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1000 def ancestor(self, a, b): |
1083 | 1001 """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
|
1002 |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1003 # 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
|
1004 if a == b: |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1005 return a |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1006 ra = self.rev(a) |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1007 rb = self.rev(b) |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1008 if ra < rb: |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1009 last = b |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1010 first = a |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1011 else: |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1012 last = a |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1013 first = b |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1014 |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1015 # 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
|
1016 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
|
1017 if first in reachable: |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1018 return first |
416d8b2a75b8
Speedup revlog.ancestors for the linear case
Chris Mason <mason@suse.com>
parents:
2080
diff
changeset
|
1019 |
147 | 1020 # calculate the distance of every node from root |
1021 dist = {nullid: 0} | |
1022 for i in xrange(self.count()): | |
1023 n = self.node(i) | |
1024 p1, p2 = self.parents(n) | |
1025 dist[n] = max(dist[p1], dist[p2]) + 1 | |
515 | 1026 |
147 | 1027 # traverse ancestors in order of decreasing distance from root |
1028 def ancestors(node): | |
1029 # we store negative distances because heap returns smallest member | |
1030 h = [(-dist[node], node)] | |
1031 seen = {} | |
1032 while h: | |
1033 d, n = heapq.heappop(h) | |
1034 if n not in seen: | |
1035 seen[n] = 1 | |
1351
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1036 yield (-d, n) |
147 | 1037 for p in self.parents(n): |
1038 heapq.heappush(h, (-dist[p], p)) | |
45
f2b2d5daec30
Fix recursion depth trouble with ancestor algorithm
mpm@selenic.com
parents:
41
diff
changeset
|
1039 |
1351
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1040 def generations(node): |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1041 sg, s = None, {} |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1042 for g,n in ancestors(node): |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1043 if g != sg: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1044 if sg: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1045 yield sg, s |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1046 sg, s = g, {n:1} |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1047 else: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1048 s[n] = 1 |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1049 yield sg, s |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1050 |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1051 x = generations(a) |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1052 y = generations(b) |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1053 gx = x.next() |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1054 gy = y.next() |
45
f2b2d5daec30
Fix recursion depth trouble with ancestor algorithm
mpm@selenic.com
parents:
41
diff
changeset
|
1055 |
147 | 1056 # increment each ancestor list until it is closer to root than |
1057 # the other, or they match | |
1058 while 1: | |
1351
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1059 #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
|
1060 if gx[0] == gy[0]: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1061 # find the intersection |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1062 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
|
1063 if i: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1064 return i[0] |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1065 else: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1066 #print "next" |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1067 gy = y.next() |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1068 gx = x.next() |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1069 elif gx[0] < gy[0]: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1070 #print "next y" |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1071 gy = y.next() |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1072 else: |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1073 #print "next x" |
0e2be889ccd7
Repair ancestor logic, fix up test cases
Matt Mackall <mpm@selenic.com>
parents:
1325
diff
changeset
|
1074 gx = x.next() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1075 |
1598
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
1076 def group(self, nodelist, lookup, infocollect=None): |
1083 | 1077 """calculate a delta group |
46 | 1078 |
1083 | 1079 Given a list of changeset revs, return a set of deltas and |
1080 metadata corresponding to nodes. the first delta is | |
1081 parent(nodes[0]) -> nodes[0] the receiver is guaranteed to | |
1082 have this parent as it has all history before these | |
1083 changesets. parent is parent[0] | |
1084 """ | |
1458
1033892bbb87
This changes the revlog.group and re-implements the localrepo.changeroup
Eric Hopper <hopper@omnifarious.org>
parents:
1457
diff
changeset
|
1085 revs = [self.rev(n) for n in nodelist] |
46 | 1086 |
1087 # if we don't have any revisions touched by these changesets, bail | |
192 | 1088 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
|
1089 yield changegroup.closechunk() |
192 | 1090 return |
46 | 1091 |
1092 # add the parent of the first rev | |
1093 p = self.parents(self.node(revs[0]))[0] | |
1094 revs.insert(0, self.rev(p)) | |
1095 | |
1096 # build deltas | |
71
47c9a869adee
Add mdiff.patches to speed up applying thousands of patches to the manifest
mpm@selenic.com
parents:
67
diff
changeset
|
1097 for d in xrange(0, len(revs) - 1): |
46 | 1098 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
|
1099 nb = self.node(b) |
192 | 1100 |
1458
1033892bbb87
This changes the revlog.group and re-implements the localrepo.changeroup
Eric Hopper <hopper@omnifarious.org>
parents:
1457
diff
changeset
|
1101 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
|
1102 infocollect(nb) |
1458
1033892bbb87
This changes the revlog.group and re-implements the localrepo.changeroup
Eric Hopper <hopper@omnifarious.org>
parents:
1457
diff
changeset
|
1103 |
1941
7518823709a2
revlog.py: factorization and fixes for rev < 0 (nullid)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1853
diff
changeset
|
1104 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
|
1105 p = self.parents(nb) |
14d1f1868bf6
cleanup of revlog.group when repository is local
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1559
diff
changeset
|
1106 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
|
1107 yield changegroup.genchunk("%s%s" % (meta, d)) |
46 | 1108 |
1981
736b6c96bbbc
make incoming work via ssh (issue139); move chunk code into separate module.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1941
diff
changeset
|
1109 yield changegroup.closechunk() |
192 | 1110 |
1062 | 1111 def addgroup(self, revs, linkmapper, transaction, unique=0): |
1083 | 1112 """ |
1113 add a delta group | |
46 | 1114 |
1083 | 1115 given a set of deltas, add them to the revision log. the |
1116 first delta is against its parent, which should be in our | |
1117 log, the rest are against the previous delta. | |
1118 """ | |
1119 | |
1120 #track the base of the current delta log | |
46 | 1121 r = self.count() |
1122 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
|
1123 node = None |
515 | 1124 |
655 | 1125 base = prev = -1 |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1126 start = end = textlen = 0 |
46 | 1127 if r: |
1128 end = self.end(t) | |
1129 | |
2072 | 1130 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
|
1131 ifh.seek(0, 2) |
2084 | 1132 transaction.add(self.indexfile, ifh.tell(), self.count()) |
2073 | 1133 if self.inlinedata(): |
1134 dfh = None | |
1135 else: | |
1136 transaction.add(self.datafile, end) | |
1137 dfh = self.opener(self.datafile, "a") | |
46 | 1138 |
1139 # loop through our set of deltas | |
192 | 1140 chain = None |
1141 for chunk in revs: | |
1142 node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80]) | |
94 | 1143 link = linkmapper(cs) |
77 | 1144 if node in self.nodemap: |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
221
diff
changeset
|
1145 # 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
|
1146 # 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
|
1147 # 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
|
1148 chain = node |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
221
diff
changeset
|
1149 continue |
192 | 1150 delta = chunk[80:] |
1151 | |
1509
46a07392cf28
Add safety check for addgroup
Matt Mackall <mpm@selenic.com>
parents:
1494
diff
changeset
|
1152 for p in (p1, p2): |
46a07392cf28
Add safety check for addgroup
Matt Mackall <mpm@selenic.com>
parents:
1494
diff
changeset
|
1153 if not p in self.nodemap: |
2295
9c15f85e61b1
fix a typo in an error message
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2289
diff
changeset
|
1154 raise RevlogError(_("unknown parent %s") % short(p)) |
1509
46a07392cf28
Add safety check for addgroup
Matt Mackall <mpm@selenic.com>
parents:
1494
diff
changeset
|
1155 |
192 | 1156 if not chain: |
1157 # retrieve the parent revision of the delta chain | |
1158 chain = p1 | |
1159 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
|
1160 raise RevlogError(_("unknown base %s") % short(chain[:4])) |
46 | 1161 |
1162 # full versions are inserted when the needed deltas become | |
1163 # comparable to the uncompressed text or when the previous | |
1164 # version is not the one we have a delta against. We use | |
1165 # the size of the previous full rev as a proxy for the | |
1166 # current size. | |
1167 | |
1168 if chain == prev: | |
1533
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
1169 tempd = compress(delta) |
3d11f81c9145
Reduce string duplication in compression code
mason@suse.com
parents:
1509
diff
changeset
|
1170 cdelta = tempd[0] + tempd[1] |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1171 textlen = mdiff.patchedsize(textlen, delta) |
46 | 1172 |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1173 if chain != prev or (end - start + len(cdelta)) > textlen * 2: |
46 | 1174 # flush our writes here so we can read it in revision |
2072 | 1175 if dfh: |
1176 dfh.flush() | |
46 | 1177 ifh.flush() |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1178 text = self.revision(chain) |
73 | 1179 text = self.patches(text, [delta]) |
46 | 1180 chk = self.addrevision(text, transaction, link, p1, p2) |
1181 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
|
1182 raise RevlogError(_("consistency error adding group")) |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1183 textlen = len(text) |
46 | 1184 else: |
2142
8a1e2a9c7013
Replaced 0 with REVLOGV0 where this meaning is used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
2141
diff
changeset
|
1185 if self.version == REVLOGV0: |
2072 | 1186 e = (end, len(cdelta), base, link, p1, p2, node) |
1187 else: | |
2078
441ea218414e
Fill in the uncompressed size during revlog.addgroup
mason@suse.com
parents:
2077
diff
changeset
|
1188 e = (self.offset_type(end, 0), len(cdelta), textlen, base, |
2072 | 1189 link, self.rev(p1), self.rev(p2), node) |
46 | 1190 self.index.append(e) |
1191 self.nodemap[node] = r | |
2073 | 1192 if self.inlinedata(): |
1193 ifh.write(struct.pack(self.indexformat, *e)) | |
1194 ifh.write(cdelta) | |
2075
343aeefb553b
Make the appendfile class inline-data index friendly
mason@suse.com
parents:
2073
diff
changeset
|
1195 self.checkinlinesize(transaction, ifh) |
2073 | 1196 if not self.inlinedata(): |
1197 dfh = self.opener(self.datafile, "a") | |
1198 ifh = self.opener(self.indexfile, "a") | |
1199 else: | |
1200 if not dfh: | |
1201 # addrevision switched from inline to conventional | |
1202 # reopen the index | |
1203 dfh = self.opener(self.datafile, "a") | |
1204 ifh = self.opener(self.indexfile, "a") | |
1205 dfh.write(cdelta) | |
1206 ifh.write(struct.pack(self.indexformat, *e)) | |
46 | 1207 |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1208 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
|
1209 base = self.base(t) |
d457fec76ab0
fix warnings from pychecker (unused variables and shadowing)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1711
diff
changeset
|
1210 start = self.start(base) |
46 | 1211 end = self.end(t) |
1212 | |
1213 return node | |
1493
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1214 |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1215 def strip(self, rev, minlink): |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1216 if self.count() == 0 or 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 |
2072 | 1219 if isinstance(self.index, lazyindex): |
1220 self.loadindexmap() | |
1221 | |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1222 # 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
|
1223 # does not actually belong to an older changeset. |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1224 # The minlink parameter defines the oldest revision |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1225 # we're allowed to strip away. |
2072 | 1226 while minlink > self.index[rev][-4]: |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1227 rev += 1 |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1228 if rev >= self.count(): |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1229 return |
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 # first truncate the files on disk |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1232 end = self.start(rev) |
2073 | 1233 if not self.inlinedata(): |
1234 df = self.opener(self.datafile, "a") | |
1235 df.truncate(end) | |
1236 end = rev * struct.calcsize(self.indexformat) | |
1237 else: | |
1238 end += rev * struct.calcsize(self.indexformat) | |
2072 | 1239 |
1240 indexf = self.opener(self.indexfile, "a") | |
1241 indexf.truncate(end) | |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1242 |
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1243 # 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
|
1244 self.cache = None |
1711 | 1245 self.chunkcache = None |
2072 | 1246 for x in xrange(rev, self.count()): |
1247 del self.nodemap[self.node(x)] | |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1248 |
2072 | 1249 del self.index[rev:] |
1535
7ae0ce7a3dc4
Add revlog.strip to truncate away revisions.
mason@suse.com
parents:
1533
diff
changeset
|
1250 |
1493
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1251 def checksize(self): |
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1252 expected = 0 |
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1253 if self.count(): |
1a216cb4ee64
verify: add check for mismatch of index and data length
Matt Mackall <mpm@selenic.com>
parents:
1469
diff
changeset
|
1254 expected = self.end(self.count() - 1) |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1255 |
1494
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1256 try: |
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1257 f = self.opener(self.datafile) |
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1258 f.seek(0, 2) |
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1259 actual = f.tell() |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1260 dd = actual - expected |
1494
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1261 except IOError, inst: |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1262 if inst.errno != errno.ENOENT: |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1263 raise |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1264 dd = 0 |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1265 |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1266 try: |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1267 f = self.opener(self.indexfile) |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1268 f.seek(0, 2) |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1269 actual = f.tell() |
2072 | 1270 s = struct.calcsize(self.indexformat) |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1271 i = actual / s |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1272 di = actual - (i * s) |
2073 | 1273 if self.inlinedata(): |
1274 databytes = 0 | |
1275 for r in xrange(self.count()): | |
1276 databytes += self.length(r) | |
1277 dd = 0 | |
1278 di = actual - self.count() * s - databytes | |
1667
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1279 except IOError, inst: |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1280 if inst.errno != errno.ENOENT: |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1281 raise |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1282 di = 0 |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1283 |
daff3ef0de8d
verify: notice extra data in indices
Matt Mackall <mpm@selenic.com>
parents:
1660
diff
changeset
|
1284 return (dd, di) |
1494
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1285 |
249ca10d37f4
Handle empty logs in repo.checksize
Matt Mackall <mpm@selenic.com>
parents:
1493
diff
changeset
|
1286 |