comparison mercurial/changegroup.py @ 14141:bd1cbfe5db5c

bundler: make parsechunk return the base revision of the delta
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Sat, 30 Apr 2011 10:00:41 +0200
parents aaa9a5989405
children da635d3c5620
comparison
equal deleted inserted replaced
14140:82f0412ef7de 14141:bd1cbfe5db5c
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from i18n import _ 8 from i18n import _
9 import util 9 import util
10 import struct, os, bz2, zlib, tempfile 10 import struct, os, bz2, zlib, tempfile
11
12 _BUNDLE10_DELTA_HEADER = "20s20s20s20s"
11 13
12 def readexactly(stream, n): 14 def readexactly(stream, n):
13 '''read n bytes from stream.read and abort if less was available''' 15 '''read n bytes from stream.read and abort if less was available'''
14 s = stream.read(n) 16 s = stream.read(n)
15 if len(s) < n: 17 if len(s) < n:
126 else: 128 else:
127 raise util.Abort("unknown bundle compression '%s'" % alg) 129 raise util.Abort("unknown bundle compression '%s'" % alg)
128 return util.chunkbuffer(generator(fh)) 130 return util.chunkbuffer(generator(fh))
129 131
130 class unbundle10(object): 132 class unbundle10(object):
133 deltaheader = _BUNDLE10_DELTA_HEADER
134 deltaheadersize = struct.calcsize(deltaheader)
131 def __init__(self, fh, alg): 135 def __init__(self, fh, alg):
132 self._stream = decompressor(fh, alg) 136 self._stream = decompressor(fh, alg)
133 self._type = alg 137 self._type = alg
134 self.callback = None 138 self.callback = None
135 def compressed(self): 139 def compressed(self):
157 def chunk(self): 161 def chunk(self):
158 """return the next chunk from changegroup 'source' as a string""" 162 """return the next chunk from changegroup 'source' as a string"""
159 l = self.chunklength() 163 l = self.chunklength()
160 return readexactly(self._stream, l) 164 return readexactly(self._stream, l)
161 165
162 def parsechunk(self): 166 def _deltaheader(self, headertuple, prevnode):
167 node, p1, p2, cs = headertuple
168 if prevnode is None:
169 deltabase = p1
170 else:
171 deltabase = prevnode
172 return node, p1, p2, deltabase, cs
173
174 def parsechunk(self, prevnode):
163 l = self.chunklength() 175 l = self.chunklength()
164 if not l: 176 if not l:
165 return {} 177 return {}
166 h = readexactly(self._stream, 80) 178 headerdata = readexactly(self._stream, self.deltaheadersize)
167 node, p1, p2, cs = struct.unpack("20s20s20s20s", h) 179 header = struct.unpack(self.deltaheader, headerdata)
168 data = readexactly(self._stream, l - 80) 180 delta = readexactly(self._stream, l - self.deltaheadersize)
169 return dict(node=node, p1=p1, p2=p2, cs=cs, data=data) 181 node, p1, p2, deltabase, cs = self._deltaheader(header, prevnode)
182 return dict(node=node, p1=p1, p2=p2, cs=cs,
183 deltabase=deltabase, delta=delta)
170 184
171 class headerlessfixup(object): 185 class headerlessfixup(object):
172 def __init__(self, fh, h): 186 def __init__(self, fh, h):
173 self._h = h 187 self._h = h
174 self._fh = fh 188 self._fh = fh