equal
deleted
inserted
replaced
39 # read the whole index for now, handle on-demand later |
39 # read the whole index for now, handle on-demand later |
40 try: |
40 try: |
41 n = 0 |
41 n = 0 |
42 i = self.opener(self.indexfile).read() |
42 i = self.opener(self.indexfile).read() |
43 s = struct.calcsize(indexformat) |
43 s = struct.calcsize(indexformat) |
44 for f in range(0, len(i), s): |
44 for f in xrange(0, len(i), s): |
45 # offset, size, base, linkrev, p1, p2, nodeid |
45 # offset, size, base, linkrev, p1, p2, nodeid |
46 e = struct.unpack(indexformat, i[f:f + s]) |
46 e = struct.unpack(indexformat, i[f:f + s]) |
47 self.nodemap[e[6]] = n |
47 self.nodemap[e[6]] = n |
48 self.index.append(e) |
48 self.index.append(e) |
49 n += 1 |
49 n += 1 |
85 yield self.revision(node) |
85 yield self.revision(node) |
86 |
86 |
87 def diff(self, a, b): |
87 def diff(self, a, b): |
88 return mdiff.textdiff(a, b) |
88 return mdiff.textdiff(a, b) |
89 |
89 |
90 def patch(self, text, patch): |
|
91 return mdiff.patch(text, patch) |
|
92 |
|
93 def revision(self, node): |
90 def revision(self, node): |
94 if node == nullid: return "" |
91 if node == nullid: return "" |
95 if self.cache and self.cache[0] == node: return self.cache[2] |
92 if self.cache and self.cache[0] == node: return self.cache[2] |
96 |
93 |
97 text = None |
94 text = None |
112 |
109 |
113 if not text: |
110 if not text: |
114 last = self.length(base) |
111 last = self.length(base) |
115 text = decompress(data[:last]) |
112 text = decompress(data[:last]) |
116 |
113 |
|
114 bins = [] |
117 for r in xrange(base + 1, rev + 1): |
115 for r in xrange(base + 1, rev + 1): |
118 s = self.length(r) |
116 s = self.length(r) |
119 b = decompress(data[last:last + s]) |
117 bins.append(decompress(data[last:last + s])) |
120 text = self.patch(text, b) |
|
121 last = last + s |
118 last = last + s |
|
119 |
|
120 text = mdiff.patches(text, bins) |
122 |
121 |
123 (p1, p2) = self.parents(node) |
122 (p1, p2) = self.parents(node) |
124 if node != hash(text, p1, p2): |
123 if node != hash(text, p1, p2): |
125 raise "integrity check failed on %s:%d" % (self.datafile, rev) |
124 raise "integrity check failed on %s:%d" % (self.datafile, rev) |
126 |
125 |
299 chunks[r] = data[pos: pos + l] |
298 chunks[r] = data[pos: pos + l] |
300 pos += l |
299 pos += l |
301 |
300 |
302 # helper to reconstruct intermediate versions |
301 # helper to reconstruct intermediate versions |
303 def construct(text, base, rev): |
302 def construct(text, base, rev): |
304 for r in range(base + 1, rev + 1): |
303 bins = [decompress(chunks[r]) for r in xrange(base + 1, rev + 1)] |
305 b = decompress(chunks[r]) |
304 return mdiff.patches(text, bins) |
306 text = self.patch(text, b) |
|
307 return text |
|
308 |
305 |
309 # build deltas |
306 # build deltas |
310 deltas = [] |
307 deltas = [] |
311 for d in range(0, len(revs) - 1): |
308 for d in xrange(0, len(revs) - 1): |
312 a, b = revs[d], revs[d + 1] |
309 a, b = revs[d], revs[d + 1] |
313 n = self.node(b) |
310 n = self.node(b) |
314 |
311 |
315 if a + 1 != b or self.base(b) == b: |
312 if a + 1 != b or self.base(b) == b: |
316 if a >= 0: |
313 if a >= 0: |