##// END OF EJS Templates
changegroup: restore default node ordering (issue6001)...
Boris Feld -
r40484:634b4531 stable
parent child Browse files
Show More
@@ -1,480 +1,480 b''
1 # storageutil.py - Storage functionality agnostic of backend implementation.
1 # storageutil.py - Storage functionality agnostic of backend implementation.
2 #
2 #
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
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 __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import hashlib
10 import hashlib
11 import re
11 import re
12 import struct
12 import struct
13
13
14 from ..i18n import _
14 from ..i18n import _
15 from ..node import (
15 from ..node import (
16 bin,
16 bin,
17 nullid,
17 nullid,
18 nullrev,
18 nullrev,
19 )
19 )
20 from .. import (
20 from .. import (
21 dagop,
21 dagop,
22 error,
22 error,
23 mdiff,
23 mdiff,
24 pycompat,
24 pycompat,
25 )
25 )
26
26
27 _nullhash = hashlib.sha1(nullid)
27 _nullhash = hashlib.sha1(nullid)
28
28
29 def hashrevisionsha1(text, p1, p2):
29 def hashrevisionsha1(text, p1, p2):
30 """Compute the SHA-1 for revision data and its parents.
30 """Compute the SHA-1 for revision data and its parents.
31
31
32 This hash combines both the current file contents and its history
32 This hash combines both the current file contents and its history
33 in a manner that makes it easy to distinguish nodes with the same
33 in a manner that makes it easy to distinguish nodes with the same
34 content in the revision graph.
34 content in the revision graph.
35 """
35 """
36 # As of now, if one of the parent node is null, p2 is null
36 # As of now, if one of the parent node is null, p2 is null
37 if p2 == nullid:
37 if p2 == nullid:
38 # deep copy of a hash is faster than creating one
38 # deep copy of a hash is faster than creating one
39 s = _nullhash.copy()
39 s = _nullhash.copy()
40 s.update(p1)
40 s.update(p1)
41 else:
41 else:
42 # none of the parent nodes are nullid
42 # none of the parent nodes are nullid
43 if p1 < p2:
43 if p1 < p2:
44 a = p1
44 a = p1
45 b = p2
45 b = p2
46 else:
46 else:
47 a = p2
47 a = p2
48 b = p1
48 b = p1
49 s = hashlib.sha1(a)
49 s = hashlib.sha1(a)
50 s.update(b)
50 s.update(b)
51 s.update(text)
51 s.update(text)
52 return s.digest()
52 return s.digest()
53
53
54 METADATA_RE = re.compile(b'\x01\n')
54 METADATA_RE = re.compile(b'\x01\n')
55
55
56 def parsemeta(text):
56 def parsemeta(text):
57 """Parse metadata header from revision data.
57 """Parse metadata header from revision data.
58
58
59 Returns a 2-tuple of (metadata, offset), where both can be None if there
59 Returns a 2-tuple of (metadata, offset), where both can be None if there
60 is no metadata.
60 is no metadata.
61 """
61 """
62 # text can be buffer, so we can't use .startswith or .index
62 # text can be buffer, so we can't use .startswith or .index
63 if text[:2] != b'\x01\n':
63 if text[:2] != b'\x01\n':
64 return None, None
64 return None, None
65 s = METADATA_RE.search(text, 2).start()
65 s = METADATA_RE.search(text, 2).start()
66 mtext = text[2:s]
66 mtext = text[2:s]
67 meta = {}
67 meta = {}
68 for l in mtext.splitlines():
68 for l in mtext.splitlines():
69 k, v = l.split(b': ', 1)
69 k, v = l.split(b': ', 1)
70 meta[k] = v
70 meta[k] = v
71 return meta, s + 2
71 return meta, s + 2
72
72
73 def packmeta(meta, text):
73 def packmeta(meta, text):
74 """Add metadata to fulltext to produce revision text."""
74 """Add metadata to fulltext to produce revision text."""
75 keys = sorted(meta)
75 keys = sorted(meta)
76 metatext = b''.join(b'%s: %s\n' % (k, meta[k]) for k in keys)
76 metatext = b''.join(b'%s: %s\n' % (k, meta[k]) for k in keys)
77 return b'\x01\n%s\x01\n%s' % (metatext, text)
77 return b'\x01\n%s\x01\n%s' % (metatext, text)
78
78
79 def iscensoredtext(text):
79 def iscensoredtext(text):
80 meta = parsemeta(text)[0]
80 meta = parsemeta(text)[0]
81 return meta and b'censored' in meta
81 return meta and b'censored' in meta
82
82
83 def filtermetadata(text):
83 def filtermetadata(text):
84 """Extract just the revision data from source text.
84 """Extract just the revision data from source text.
85
85
86 Returns ``text`` unless it has a metadata header, in which case we return
86 Returns ``text`` unless it has a metadata header, in which case we return
87 a new buffer without hte metadata.
87 a new buffer without hte metadata.
88 """
88 """
89 if not text.startswith(b'\x01\n'):
89 if not text.startswith(b'\x01\n'):
90 return text
90 return text
91
91
92 offset = text.index(b'\x01\n', 2)
92 offset = text.index(b'\x01\n', 2)
93 return text[offset + 2:]
93 return text[offset + 2:]
94
94
95 def filerevisioncopied(store, node):
95 def filerevisioncopied(store, node):
96 """Resolve file revision copy metadata.
96 """Resolve file revision copy metadata.
97
97
98 Returns ``False`` if the file has no copy metadata. Otherwise a
98 Returns ``False`` if the file has no copy metadata. Otherwise a
99 2-tuple of the source filename and node.
99 2-tuple of the source filename and node.
100 """
100 """
101 if store.parents(node)[0] != nullid:
101 if store.parents(node)[0] != nullid:
102 return False
102 return False
103
103
104 meta = parsemeta(store.revision(node))[0]
104 meta = parsemeta(store.revision(node))[0]
105
105
106 # copy and copyrev occur in pairs. In rare cases due to old bugs,
106 # copy and copyrev occur in pairs. In rare cases due to old bugs,
107 # one can occur without the other. So ensure both are present to flag
107 # one can occur without the other. So ensure both are present to flag
108 # as a copy.
108 # as a copy.
109 if meta and b'copy' in meta and b'copyrev' in meta:
109 if meta and b'copy' in meta and b'copyrev' in meta:
110 return meta[b'copy'], bin(meta[b'copyrev'])
110 return meta[b'copy'], bin(meta[b'copyrev'])
111
111
112 return False
112 return False
113
113
114 def filedataequivalent(store, node, filedata):
114 def filedataequivalent(store, node, filedata):
115 """Determines whether file data is equivalent to a stored node.
115 """Determines whether file data is equivalent to a stored node.
116
116
117 Returns True if the passed file data would hash to the same value
117 Returns True if the passed file data would hash to the same value
118 as a stored revision and False otherwise.
118 as a stored revision and False otherwise.
119
119
120 When a stored revision is censored, filedata must be empty to have
120 When a stored revision is censored, filedata must be empty to have
121 equivalence.
121 equivalence.
122
122
123 When a stored revision has copy metadata, it is ignored as part
123 When a stored revision has copy metadata, it is ignored as part
124 of the compare.
124 of the compare.
125 """
125 """
126
126
127 if filedata.startswith(b'\x01\n'):
127 if filedata.startswith(b'\x01\n'):
128 revisiontext = b'\x01\n\x01\n' + filedata
128 revisiontext = b'\x01\n\x01\n' + filedata
129 else:
129 else:
130 revisiontext = filedata
130 revisiontext = filedata
131
131
132 p1, p2 = store.parents(node)
132 p1, p2 = store.parents(node)
133
133
134 computednode = hashrevisionsha1(revisiontext, p1, p2)
134 computednode = hashrevisionsha1(revisiontext, p1, p2)
135
135
136 if computednode == node:
136 if computednode == node:
137 return True
137 return True
138
138
139 # Censored files compare against the empty file.
139 # Censored files compare against the empty file.
140 if store.iscensored(store.rev(node)):
140 if store.iscensored(store.rev(node)):
141 return filedata == b''
141 return filedata == b''
142
142
143 # Renaming a file produces a different hash, even if the data
143 # Renaming a file produces a different hash, even if the data
144 # remains unchanged. Check if that's the case.
144 # remains unchanged. Check if that's the case.
145 if store.renamed(node):
145 if store.renamed(node):
146 return store.read(node) == filedata
146 return store.read(node) == filedata
147
147
148 return False
148 return False
149
149
150 def iterrevs(storelen, start=0, stop=None):
150 def iterrevs(storelen, start=0, stop=None):
151 """Iterate over revision numbers in a store."""
151 """Iterate over revision numbers in a store."""
152 step = 1
152 step = 1
153
153
154 if stop is not None:
154 if stop is not None:
155 if start > stop:
155 if start > stop:
156 step = -1
156 step = -1
157 stop += step
157 stop += step
158 if stop > storelen:
158 if stop > storelen:
159 stop = storelen
159 stop = storelen
160 else:
160 else:
161 stop = storelen
161 stop = storelen
162
162
163 return pycompat.xrange(start, stop, step)
163 return pycompat.xrange(start, stop, step)
164
164
165 def fileidlookup(store, fileid, identifier):
165 def fileidlookup(store, fileid, identifier):
166 """Resolve the file node for a value.
166 """Resolve the file node for a value.
167
167
168 ``store`` is an object implementing the ``ifileindex`` interface.
168 ``store`` is an object implementing the ``ifileindex`` interface.
169
169
170 ``fileid`` can be:
170 ``fileid`` can be:
171
171
172 * A 20 byte binary node.
172 * A 20 byte binary node.
173 * An integer revision number
173 * An integer revision number
174 * A 40 byte hex node.
174 * A 40 byte hex node.
175 * A bytes that can be parsed as an integer representing a revision number.
175 * A bytes that can be parsed as an integer representing a revision number.
176
176
177 ``identifier`` is used to populate ``error.LookupError`` with an identifier
177 ``identifier`` is used to populate ``error.LookupError`` with an identifier
178 for the store.
178 for the store.
179
179
180 Raises ``error.LookupError`` on failure.
180 Raises ``error.LookupError`` on failure.
181 """
181 """
182 if isinstance(fileid, int):
182 if isinstance(fileid, int):
183 try:
183 try:
184 return store.node(fileid)
184 return store.node(fileid)
185 except IndexError:
185 except IndexError:
186 raise error.LookupError('%d' % fileid, identifier,
186 raise error.LookupError('%d' % fileid, identifier,
187 _('no match found'))
187 _('no match found'))
188
188
189 if len(fileid) == 20:
189 if len(fileid) == 20:
190 try:
190 try:
191 store.rev(fileid)
191 store.rev(fileid)
192 return fileid
192 return fileid
193 except error.LookupError:
193 except error.LookupError:
194 pass
194 pass
195
195
196 if len(fileid) == 40:
196 if len(fileid) == 40:
197 try:
197 try:
198 rawnode = bin(fileid)
198 rawnode = bin(fileid)
199 store.rev(rawnode)
199 store.rev(rawnode)
200 return rawnode
200 return rawnode
201 except TypeError:
201 except TypeError:
202 pass
202 pass
203
203
204 try:
204 try:
205 rev = int(fileid)
205 rev = int(fileid)
206
206
207 if b'%d' % rev != fileid:
207 if b'%d' % rev != fileid:
208 raise ValueError
208 raise ValueError
209
209
210 try:
210 try:
211 return store.node(rev)
211 return store.node(rev)
212 except (IndexError, TypeError):
212 except (IndexError, TypeError):
213 pass
213 pass
214 except (ValueError, OverflowError):
214 except (ValueError, OverflowError):
215 pass
215 pass
216
216
217 raise error.LookupError(fileid, identifier, _('no match found'))
217 raise error.LookupError(fileid, identifier, _('no match found'))
218
218
219 def resolvestripinfo(minlinkrev, tiprev, headrevs, linkrevfn, parentrevsfn):
219 def resolvestripinfo(minlinkrev, tiprev, headrevs, linkrevfn, parentrevsfn):
220 """Resolve information needed to strip revisions.
220 """Resolve information needed to strip revisions.
221
221
222 Finds the minimum revision number that must be stripped in order to
222 Finds the minimum revision number that must be stripped in order to
223 strip ``minlinkrev``.
223 strip ``minlinkrev``.
224
224
225 Returns a 2-tuple of the minimum revision number to do that and a set
225 Returns a 2-tuple of the minimum revision number to do that and a set
226 of all revision numbers that have linkrevs that would be broken
226 of all revision numbers that have linkrevs that would be broken
227 by that strip.
227 by that strip.
228
228
229 ``tiprev`` is the current tip-most revision. It is ``len(store) - 1``.
229 ``tiprev`` is the current tip-most revision. It is ``len(store) - 1``.
230 ``headrevs`` is an iterable of head revisions.
230 ``headrevs`` is an iterable of head revisions.
231 ``linkrevfn`` is a callable that receives a revision and returns a linked
231 ``linkrevfn`` is a callable that receives a revision and returns a linked
232 revision.
232 revision.
233 ``parentrevsfn`` is a callable that receives a revision number and returns
233 ``parentrevsfn`` is a callable that receives a revision number and returns
234 an iterable of its parent revision numbers.
234 an iterable of its parent revision numbers.
235 """
235 """
236 brokenrevs = set()
236 brokenrevs = set()
237 strippoint = tiprev + 1
237 strippoint = tiprev + 1
238
238
239 heads = {}
239 heads = {}
240 futurelargelinkrevs = set()
240 futurelargelinkrevs = set()
241 for head in headrevs:
241 for head in headrevs:
242 headlinkrev = linkrevfn(head)
242 headlinkrev = linkrevfn(head)
243 heads[head] = headlinkrev
243 heads[head] = headlinkrev
244 if headlinkrev >= minlinkrev:
244 if headlinkrev >= minlinkrev:
245 futurelargelinkrevs.add(headlinkrev)
245 futurelargelinkrevs.add(headlinkrev)
246
246
247 # This algorithm involves walking down the rev graph, starting at the
247 # This algorithm involves walking down the rev graph, starting at the
248 # heads. Since the revs are topologically sorted according to linkrev,
248 # heads. Since the revs are topologically sorted according to linkrev,
249 # once all head linkrevs are below the minlink, we know there are
249 # once all head linkrevs are below the minlink, we know there are
250 # no more revs that could have a linkrev greater than minlink.
250 # no more revs that could have a linkrev greater than minlink.
251 # So we can stop walking.
251 # So we can stop walking.
252 while futurelargelinkrevs:
252 while futurelargelinkrevs:
253 strippoint -= 1
253 strippoint -= 1
254 linkrev = heads.pop(strippoint)
254 linkrev = heads.pop(strippoint)
255
255
256 if linkrev < minlinkrev:
256 if linkrev < minlinkrev:
257 brokenrevs.add(strippoint)
257 brokenrevs.add(strippoint)
258 else:
258 else:
259 futurelargelinkrevs.remove(linkrev)
259 futurelargelinkrevs.remove(linkrev)
260
260
261 for p in parentrevsfn(strippoint):
261 for p in parentrevsfn(strippoint):
262 if p != nullrev:
262 if p != nullrev:
263 plinkrev = linkrevfn(p)
263 plinkrev = linkrevfn(p)
264 heads[p] = plinkrev
264 heads[p] = plinkrev
265 if plinkrev >= minlinkrev:
265 if plinkrev >= minlinkrev:
266 futurelargelinkrevs.add(plinkrev)
266 futurelargelinkrevs.add(plinkrev)
267
267
268 return strippoint, brokenrevs
268 return strippoint, brokenrevs
269
269
270 def emitrevisions(store, nodes, nodesorder, resultcls, deltaparentfn=None,
270 def emitrevisions(store, nodes, nodesorder, resultcls, deltaparentfn=None,
271 candeltafn=None, rawsizefn=None, revdifffn=None, flagsfn=None,
271 candeltafn=None, rawsizefn=None, revdifffn=None, flagsfn=None,
272 sendfulltext=False,
272 sendfulltext=False,
273 revisiondata=False, assumehaveparentrevisions=False,
273 revisiondata=False, assumehaveparentrevisions=False,
274 deltaprevious=False):
274 deltaprevious=False):
275 """Generic implementation of ifiledata.emitrevisions().
275 """Generic implementation of ifiledata.emitrevisions().
276
276
277 Emitting revision data is subtly complex. This function attempts to
277 Emitting revision data is subtly complex. This function attempts to
278 encapsulate all the logic for doing so in a backend-agnostic way.
278 encapsulate all the logic for doing so in a backend-agnostic way.
279
279
280 ``store``
280 ``store``
281 Object conforming to ``ifilestorage`` interface.
281 Object conforming to ``ifilestorage`` interface.
282
282
283 ``nodes``
283 ``nodes``
284 List of revision nodes whose data to emit.
284 List of revision nodes whose data to emit.
285
285
286 ``resultcls``
286 ``resultcls``
287 A type implementing the ``irevisiondelta`` interface that will be
287 A type implementing the ``irevisiondelta`` interface that will be
288 constructed and returned.
288 constructed and returned.
289
289
290 ``deltaparentfn`` (optional)
290 ``deltaparentfn`` (optional)
291 Callable receiving a revision number and returning the revision number
291 Callable receiving a revision number and returning the revision number
292 of a revision that the internal delta is stored against. This delta
292 of a revision that the internal delta is stored against. This delta
293 will be preferred over computing a new arbitrary delta.
293 will be preferred over computing a new arbitrary delta.
294
294
295 If not defined, a delta will always be computed from raw revision
295 If not defined, a delta will always be computed from raw revision
296 data.
296 data.
297
297
298 ``candeltafn`` (optional)
298 ``candeltafn`` (optional)
299 Callable receiving a pair of revision numbers that returns a bool
299 Callable receiving a pair of revision numbers that returns a bool
300 indicating whether a delta between them can be produced.
300 indicating whether a delta between them can be produced.
301
301
302 If not defined, it is assumed that any two revisions can delta with
302 If not defined, it is assumed that any two revisions can delta with
303 each other.
303 each other.
304
304
305 ``rawsizefn`` (optional)
305 ``rawsizefn`` (optional)
306 Callable receiving a revision number and returning the length of the
306 Callable receiving a revision number and returning the length of the
307 ``store.revision(rev, raw=True)``.
307 ``store.revision(rev, raw=True)``.
308
308
309 If not defined, ``len(store.revision(rev, raw=True))`` will be called.
309 If not defined, ``len(store.revision(rev, raw=True))`` will be called.
310
310
311 ``revdifffn`` (optional)
311 ``revdifffn`` (optional)
312 Callable receiving a pair of revision numbers that returns a delta
312 Callable receiving a pair of revision numbers that returns a delta
313 between them.
313 between them.
314
314
315 If not defined, a delta will be computed by invoking mdiff code
315 If not defined, a delta will be computed by invoking mdiff code
316 on ``store.revision()`` results.
316 on ``store.revision()`` results.
317
317
318 Defining this function allows a precomputed or stored delta to be
318 Defining this function allows a precomputed or stored delta to be
319 used without having to compute on.
319 used without having to compute on.
320
320
321 ``flagsfn`` (optional)
321 ``flagsfn`` (optional)
322 Callable receiving a revision number and returns the integer flags
322 Callable receiving a revision number and returns the integer flags
323 value for it. If not defined, flags value will be 0.
323 value for it. If not defined, flags value will be 0.
324
324
325 ``sendfulltext``
325 ``sendfulltext``
326 Whether to send fulltext revisions instead of deltas, if allowed.
326 Whether to send fulltext revisions instead of deltas, if allowed.
327
327
328 ``nodesorder``
328 ``nodesorder``
329 ``revisiondata``
329 ``revisiondata``
330 ``assumehaveparentrevisions``
330 ``assumehaveparentrevisions``
331 ``deltaprevious``
331 ``deltaprevious``
332 See ``ifiledata.emitrevisions()`` interface documentation.
332 See ``ifiledata.emitrevisions()`` interface documentation.
333 """
333 """
334
334
335 fnode = store.node
335 fnode = store.node
336 frev = store.rev
336 frev = store.rev
337
337
338 if nodesorder == 'nodes':
338 if nodesorder == 'nodes':
339 revs = [frev(n) for n in nodes]
339 revs = [frev(n) for n in nodes]
340 elif nodesorder == 'storage':
340 elif nodesorder == 'linear':
341 revs = sorted(frev(n) for n in nodes)
342 else:
343 revs = set(frev(n) for n in nodes)
341 revs = set(frev(n) for n in nodes)
344 revs = dagop.linearize(revs, store.parentrevs)
342 revs = dagop.linearize(revs, store.parentrevs)
343 else: # storage and default
344 revs = sorted(frev(n) for n in nodes)
345
345
346 prevrev = None
346 prevrev = None
347
347
348 if deltaprevious or assumehaveparentrevisions:
348 if deltaprevious or assumehaveparentrevisions:
349 prevrev = store.parentrevs(revs[0])[0]
349 prevrev = store.parentrevs(revs[0])[0]
350
350
351 # Set of revs available to delta against.
351 # Set of revs available to delta against.
352 available = set()
352 available = set()
353
353
354 for rev in revs:
354 for rev in revs:
355 if rev == nullrev:
355 if rev == nullrev:
356 continue
356 continue
357
357
358 node = fnode(rev)
358 node = fnode(rev)
359 p1rev, p2rev = store.parentrevs(rev)
359 p1rev, p2rev = store.parentrevs(rev)
360
360
361 if deltaparentfn:
361 if deltaparentfn:
362 deltaparentrev = deltaparentfn(rev)
362 deltaparentrev = deltaparentfn(rev)
363 else:
363 else:
364 deltaparentrev = nullrev
364 deltaparentrev = nullrev
365
365
366 # Forced delta against previous mode.
366 # Forced delta against previous mode.
367 if deltaprevious:
367 if deltaprevious:
368 baserev = prevrev
368 baserev = prevrev
369
369
370 # We're instructed to send fulltext. Honor that.
370 # We're instructed to send fulltext. Honor that.
371 elif sendfulltext:
371 elif sendfulltext:
372 baserev = nullrev
372 baserev = nullrev
373
373
374 # There is a delta in storage. We try to use that because it
374 # There is a delta in storage. We try to use that because it
375 # amounts to effectively copying data from storage and is
375 # amounts to effectively copying data from storage and is
376 # therefore the fastest.
376 # therefore the fastest.
377 elif deltaparentrev != nullrev:
377 elif deltaparentrev != nullrev:
378 # Base revision was already emitted in this group. We can
378 # Base revision was already emitted in this group. We can
379 # always safely use the delta.
379 # always safely use the delta.
380 if deltaparentrev in available:
380 if deltaparentrev in available:
381 baserev = deltaparentrev
381 baserev = deltaparentrev
382
382
383 # Base revision is a parent that hasn't been emitted already.
383 # Base revision is a parent that hasn't been emitted already.
384 # Use it if we can assume the receiver has the parent revision.
384 # Use it if we can assume the receiver has the parent revision.
385 elif (assumehaveparentrevisions
385 elif (assumehaveparentrevisions
386 and deltaparentrev in (p1rev, p2rev)):
386 and deltaparentrev in (p1rev, p2rev)):
387 baserev = deltaparentrev
387 baserev = deltaparentrev
388
388
389 # No guarantee the receiver has the delta parent. Send delta
389 # No guarantee the receiver has the delta parent. Send delta
390 # against last revision (if possible), which in the common case
390 # against last revision (if possible), which in the common case
391 # should be similar enough to this revision that the delta is
391 # should be similar enough to this revision that the delta is
392 # reasonable.
392 # reasonable.
393 elif prevrev is not None:
393 elif prevrev is not None:
394 baserev = prevrev
394 baserev = prevrev
395 else:
395 else:
396 baserev = nullrev
396 baserev = nullrev
397
397
398 # Storage has a fulltext revision.
398 # Storage has a fulltext revision.
399
399
400 # Let's use the previous revision, which is as good a guess as any.
400 # Let's use the previous revision, which is as good a guess as any.
401 # There is definitely room to improve this logic.
401 # There is definitely room to improve this logic.
402 elif prevrev is not None:
402 elif prevrev is not None:
403 baserev = prevrev
403 baserev = prevrev
404 else:
404 else:
405 baserev = nullrev
405 baserev = nullrev
406
406
407 # But we can't actually use our chosen delta base for whatever
407 # But we can't actually use our chosen delta base for whatever
408 # reason. Reset to fulltext.
408 # reason. Reset to fulltext.
409 if baserev != nullrev and (candeltafn and not candeltafn(baserev, rev)):
409 if baserev != nullrev and (candeltafn and not candeltafn(baserev, rev)):
410 baserev = nullrev
410 baserev = nullrev
411
411
412 revision = None
412 revision = None
413 delta = None
413 delta = None
414 baserevisionsize = None
414 baserevisionsize = None
415
415
416 if revisiondata:
416 if revisiondata:
417 if store.iscensored(baserev) or store.iscensored(rev):
417 if store.iscensored(baserev) or store.iscensored(rev):
418 try:
418 try:
419 revision = store.revision(node, raw=True)
419 revision = store.revision(node, raw=True)
420 except error.CensoredNodeError as e:
420 except error.CensoredNodeError as e:
421 revision = e.tombstone
421 revision = e.tombstone
422
422
423 if baserev != nullrev:
423 if baserev != nullrev:
424 if rawsizefn:
424 if rawsizefn:
425 baserevisionsize = rawsizefn(baserev)
425 baserevisionsize = rawsizefn(baserev)
426 else:
426 else:
427 baserevisionsize = len(store.revision(baserev,
427 baserevisionsize = len(store.revision(baserev,
428 raw=True))
428 raw=True))
429
429
430 elif baserev == nullrev and not deltaprevious:
430 elif baserev == nullrev and not deltaprevious:
431 revision = store.revision(node, raw=True)
431 revision = store.revision(node, raw=True)
432 available.add(rev)
432 available.add(rev)
433 else:
433 else:
434 if revdifffn:
434 if revdifffn:
435 delta = revdifffn(baserev, rev)
435 delta = revdifffn(baserev, rev)
436 else:
436 else:
437 delta = mdiff.textdiff(store.revision(baserev, raw=True),
437 delta = mdiff.textdiff(store.revision(baserev, raw=True),
438 store.revision(rev, raw=True))
438 store.revision(rev, raw=True))
439
439
440 available.add(rev)
440 available.add(rev)
441
441
442 yield resultcls(
442 yield resultcls(
443 node=node,
443 node=node,
444 p1node=fnode(p1rev),
444 p1node=fnode(p1rev),
445 p2node=fnode(p2rev),
445 p2node=fnode(p2rev),
446 basenode=fnode(baserev),
446 basenode=fnode(baserev),
447 flags=flagsfn(rev) if flagsfn else 0,
447 flags=flagsfn(rev) if flagsfn else 0,
448 baserevisionsize=baserevisionsize,
448 baserevisionsize=baserevisionsize,
449 revision=revision,
449 revision=revision,
450 delta=delta)
450 delta=delta)
451
451
452 prevrev = rev
452 prevrev = rev
453
453
454 def deltaiscensored(delta, baserev, baselenfn):
454 def deltaiscensored(delta, baserev, baselenfn):
455 """Determine if a delta represents censored revision data.
455 """Determine if a delta represents censored revision data.
456
456
457 ``baserev`` is the base revision this delta is encoded against.
457 ``baserev`` is the base revision this delta is encoded against.
458 ``baselenfn`` is a callable receiving a revision number that resolves the
458 ``baselenfn`` is a callable receiving a revision number that resolves the
459 length of the revision fulltext.
459 length of the revision fulltext.
460
460
461 Returns a bool indicating if the result of the delta represents a censored
461 Returns a bool indicating if the result of the delta represents a censored
462 revision.
462 revision.
463 """
463 """
464 # Fragile heuristic: unless new file meta keys are added alphabetically
464 # Fragile heuristic: unless new file meta keys are added alphabetically
465 # preceding "censored", all censored revisions are prefixed by
465 # preceding "censored", all censored revisions are prefixed by
466 # "\1\ncensored:". A delta producing such a censored revision must be a
466 # "\1\ncensored:". A delta producing such a censored revision must be a
467 # full-replacement delta, so we inspect the first and only patch in the
467 # full-replacement delta, so we inspect the first and only patch in the
468 # delta for this prefix.
468 # delta for this prefix.
469 hlen = struct.calcsize(">lll")
469 hlen = struct.calcsize(">lll")
470 if len(delta) <= hlen:
470 if len(delta) <= hlen:
471 return False
471 return False
472
472
473 oldlen = baselenfn(baserev)
473 oldlen = baselenfn(baserev)
474 newlen = len(delta) - hlen
474 newlen = len(delta) - hlen
475 if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
475 if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
476 return False
476 return False
477
477
478 add = "\1\ncensored:"
478 add = "\1\ncensored:"
479 addlen = len(add)
479 addlen = len(add)
480 return newlen >= addlen and delta[hlen:hlen + addlen] == add
480 return newlen >= addlen and delta[hlen:hlen + addlen] == add
@@ -1,402 +1,402 b''
1 #require no-reposimplestore
1 #require no-reposimplestore
2
2
3 Check whether size of generaldelta revlog is not bigger than its
3 Check whether size of generaldelta revlog is not bigger than its
4 regular equivalent. Test would fail if generaldelta was naive
4 regular equivalent. Test would fail if generaldelta was naive
5 implementation of parentdelta: third manifest revision would be fully
5 implementation of parentdelta: third manifest revision would be fully
6 inserted due to big distance from its paren revision (zero).
6 inserted due to big distance from its paren revision (zero).
7
7
8 $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
8 $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
9 $ cd repo
9 $ cd repo
10 $ echo foo > foo
10 $ echo foo > foo
11 $ echo bar > bar
11 $ echo bar > bar
12 $ echo baz > baz
12 $ echo baz > baz
13 $ hg commit -q -Am boo
13 $ hg commit -q -Am boo
14 $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
14 $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
15 $ for r in 1 2 3; do
15 $ for r in 1 2 3; do
16 > echo $r > foo
16 > echo $r > foo
17 > hg commit -q -m $r
17 > hg commit -q -m $r
18 > hg up -q -r 0
18 > hg up -q -r 0
19 > hg pull . -q -r $r -R ../gdrepo
19 > hg pull . -q -r $r -R ../gdrepo
20 > done
20 > done
21
21
22 $ cd ..
22 $ cd ..
23 >>> from __future__ import print_function
23 >>> from __future__ import print_function
24 >>> import os
24 >>> import os
25 >>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
25 >>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
26 >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
26 >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
27 >>> if regsize < gdsize:
27 >>> if regsize < gdsize:
28 ... print('generaldata increased size of manifest')
28 ... print('generaldata increased size of manifest')
29
29
30 Verify rev reordering doesnt create invalid bundles (issue4462)
30 Verify rev reordering doesnt create invalid bundles (issue4462)
31 This requires a commit tree that when pulled will reorder manifest revs such
31 This requires a commit tree that when pulled will reorder manifest revs such
32 that the second manifest to create a file rev will be ordered before the first
32 that the second manifest to create a file rev will be ordered before the first
33 manifest to create that file rev. We also need to do a partial pull to ensure
33 manifest to create that file rev. We also need to do a partial pull to ensure
34 reordering happens. At the end we verify the linkrev points at the earliest
34 reordering happens. At the end we verify the linkrev points at the earliest
35 commit.
35 commit.
36
36
37 $ hg init server --config format.generaldelta=True
37 $ hg init server --config format.generaldelta=True
38 $ cd server
38 $ cd server
39 $ touch a
39 $ touch a
40 $ hg commit -Aqm a
40 $ hg commit -Aqm a
41 $ echo x > x
41 $ echo x > x
42 $ echo y > y
42 $ echo y > y
43 $ hg commit -Aqm xy
43 $ hg commit -Aqm xy
44 $ hg up -q '.^'
44 $ hg up -q '.^'
45 $ echo x > x
45 $ echo x > x
46 $ echo z > z
46 $ echo z > z
47 $ hg commit -Aqm xz
47 $ hg commit -Aqm xz
48 $ hg up -q 1
48 $ hg up -q 1
49 $ echo b > b
49 $ echo b > b
50 $ hg commit -Aqm b
50 $ hg commit -Aqm b
51 $ hg merge -q 2
51 $ hg merge -q 2
52 $ hg commit -Aqm merge
52 $ hg commit -Aqm merge
53 $ echo c > c
53 $ echo c > c
54 $ hg commit -Aqm c
54 $ hg commit -Aqm c
55 $ hg log -G -T '{rev} {shortest(node)} {desc}'
55 $ hg log -G -T '{rev} {shortest(node)} {desc}'
56 @ 5 ebb8 c
56 @ 5 ebb8 c
57 |
57 |
58 o 4 baf7 merge
58 o 4 baf7 merge
59 |\
59 |\
60 | o 3 a129 b
60 | o 3 a129 b
61 | |
61 | |
62 o | 2 958c xz
62 o | 2 958c xz
63 | |
63 | |
64 | o 1 f00c xy
64 | o 1 f00c xy
65 |/
65 |/
66 o 0 3903 a
66 o 0 3903 a
67
67
68 $ cd ..
68 $ cd ..
69 $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=false
69 $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=false
70 $ cd client
70 $ cd client
71 $ hg pull -q ../server -r 4
71 $ hg pull -q ../server -r 4
72 $ hg debugdeltachain x
72 $ hg debugdeltachain x
73 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
73 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
74 0 1 1 -1 base 3 2 3 1.50000 3 0 0.00000
74 0 1 1 -1 base 3 2 3 1.50000 3 0 0.00000
75
75
76 $ cd ..
76 $ cd ..
77
77
78 Test "usegeneraldelta" config
78 Test "usegeneraldelta" config
79 (repo are general delta, but incoming bundle are not re-deltafied)
79 (repo are general delta, but incoming bundle are not re-deltafied)
80
80
81 delta coming from the server base delta server are not recompressed.
81 delta coming from the server base delta server are not recompressed.
82 (also include the aggressive version for comparison)
82 (also include the aggressive version for comparison)
83
83
84 $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
84 $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
85 requesting all changes
85 requesting all changes
86 adding changesets
86 adding changesets
87 adding manifests
87 adding manifests
88 adding file changes
88 adding file changes
89 added 4 changesets with 6 changes to 3 files (+2 heads)
89 added 4 changesets with 6 changes to 3 files (+2 heads)
90 new changesets 0ea3fcf9d01d:bba78d330d9c
90 new changesets 0ea3fcf9d01d:bba78d330d9c
91 updating to branch default
91 updating to branch default
92 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 $ hg clone repo --pull --config format.generaldelta=1 full
93 $ hg clone repo --pull --config format.generaldelta=1 full
94 requesting all changes
94 requesting all changes
95 adding changesets
95 adding changesets
96 adding manifests
96 adding manifests
97 adding file changes
97 adding file changes
98 added 4 changesets with 6 changes to 3 files (+2 heads)
98 added 4 changesets with 6 changes to 3 files (+2 heads)
99 new changesets 0ea3fcf9d01d:bba78d330d9c
99 new changesets 0ea3fcf9d01d:bba78d330d9c
100 updating to branch default
100 updating to branch default
101 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 $ hg -R repo debugdeltachain -m
102 $ hg -R repo debugdeltachain -m
103 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
103 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
104 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
104 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
105 1 1 2 0 prev 57 135 161 1.19259 161 0 0.00000
105 1 1 2 0 prev 57 135 161 1.19259 161 0 0.00000
106 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
106 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
107 3 2 1 -1 base 104 135 104 0.77037 104 0 0.00000
107 3 2 1 -1 base 104 135 104 0.77037 104 0 0.00000
108 $ hg -R usegd debugdeltachain -m
108 $ hg -R usegd debugdeltachain -m
109 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
109 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
110 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
110 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
111 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
111 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
112 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
112 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
113 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
113 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
114 $ hg -R full debugdeltachain -m
114 $ hg -R full debugdeltachain -m
115 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
115 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
116 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
116 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
117 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
117 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
118 2 1 2 0 p1 57 135 161 1.19259 218 57 0.35404
118 2 1 2 0 p1 57 135 161 1.19259 218 57 0.35404
119 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
119 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
120
120
121 Test revlog.optimize-delta-parent-choice
121 Test revlog.optimize-delta-parent-choice
122
122
123 $ hg init --config format.generaldelta=1 aggressive
123 $ hg init --config format.generaldelta=1 aggressive
124 $ cd aggressive
124 $ cd aggressive
125 $ cat << EOF >> .hg/hgrc
125 $ cat << EOF >> .hg/hgrc
126 > [format]
126 > [format]
127 > generaldelta = 1
127 > generaldelta = 1
128 > EOF
128 > EOF
129 $ touch a b c d e
129 $ touch a b c d e
130 $ hg commit -Aqm side1
130 $ hg commit -Aqm side1
131 $ hg up -q null
131 $ hg up -q null
132 $ touch x y
132 $ touch x y
133 $ hg commit -Aqm side2
133 $ hg commit -Aqm side2
134
134
135 - Verify non-aggressive merge uses p1 (commit 1) as delta parent
135 - Verify non-aggressive merge uses p1 (commit 1) as delta parent
136 $ hg merge -q 0
136 $ hg merge -q 0
137 $ hg commit -q -m merge
137 $ hg commit -q -m merge
138 $ hg debugdeltachain -m
138 $ hg debugdeltachain -m
139 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
139 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
140 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
140 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
141 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
141 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
142 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
142 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
143
143
144 $ hg strip -q -r . --config extensions.strip=
144 $ hg strip -q -r . --config extensions.strip=
145
145
146 - Verify aggressive merge uses p2 (commit 0) as delta parent
146 - Verify aggressive merge uses p2 (commit 0) as delta parent
147 $ hg up -q -C 1
147 $ hg up -q -C 1
148 $ hg merge -q 0
148 $ hg merge -q 0
149 $ hg commit -q -m merge --config storage.revlog.optimize-delta-parent-choice=yes
149 $ hg commit -q -m merge --config storage.revlog.optimize-delta-parent-choice=yes
150 $ hg debugdeltachain -m
150 $ hg debugdeltachain -m
151 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
151 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
152 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
152 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
153 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
153 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
154 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
154 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
155
155
156 Test that strip bundle use bundle2
156 Test that strip bundle use bundle2
157 $ hg --config extensions.strip= strip .
157 $ hg --config extensions.strip= strip .
158 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
158 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
159 saved backup bundle to $TESTTMP/aggressive/.hg/strip-backup/1c5d4dc9a8b8-6c68e60c-backup.hg
159 saved backup bundle to $TESTTMP/aggressive/.hg/strip-backup/1c5d4dc9a8b8-6c68e60c-backup.hg
160 $ hg debugbundle .hg/strip-backup/*
160 $ hg debugbundle .hg/strip-backup/*
161 Stream params: {Compression: BZ}
161 Stream params: {Compression: BZ}
162 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
162 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
163 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9
163 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9
164 cache:rev-branch-cache -- {} (mandatory: False)
164 cache:rev-branch-cache -- {} (mandatory: False)
165 phase-heads -- {} (mandatory: True)
165 phase-heads -- {} (mandatory: True)
166 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9 draft
166 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9 draft
167
167
168 $ cd ..
168 $ cd ..
169
169
170 test maxdeltachainspan
170 test maxdeltachainspan
171
171
172 $ hg init source-repo
172 $ hg init source-repo
173 $ cd source-repo
173 $ cd source-repo
174 $ hg debugbuilddag --new-file '.+5:brancha$.+11:branchb$.+30:branchc<brancha+2<branchb+2'
174 $ hg debugbuilddag --new-file '.+5:brancha$.+11:branchb$.+30:branchc<brancha+2<branchb+2'
175 # add an empty revision somewhere
175 # add an empty revision somewhere
176 $ hg up tip
176 $ hg up tip
177 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 $ hg rm .
178 $ hg rm .
179 removing nf10
179 removing nf10
180 removing nf11
180 removing nf11
181 removing nf12
181 removing nf12
182 removing nf13
182 removing nf13
183 removing nf14
183 removing nf14
184 removing nf15
184 removing nf15
185 removing nf16
185 removing nf16
186 removing nf17
186 removing nf17
187 removing nf51
187 removing nf51
188 removing nf52
188 removing nf52
189 removing nf6
189 removing nf6
190 removing nf7
190 removing nf7
191 removing nf8
191 removing nf8
192 removing nf9
192 removing nf9
193 $ hg commit -m 'empty all'
193 $ hg commit -m 'empty all'
194 $ hg revert --all --rev 'p1(.)'
194 $ hg revert --all --rev 'p1(.)'
195 adding nf10
195 adding nf10
196 adding nf11
196 adding nf11
197 adding nf12
197 adding nf12
198 adding nf13
198 adding nf13
199 adding nf14
199 adding nf14
200 adding nf15
200 adding nf15
201 adding nf16
201 adding nf16
202 adding nf17
202 adding nf17
203 adding nf51
203 adding nf51
204 adding nf52
204 adding nf52
205 adding nf6
205 adding nf6
206 adding nf7
206 adding nf7
207 adding nf8
207 adding nf8
208 adding nf9
208 adding nf9
209 $ hg commit -m 'restore all'
209 $ hg commit -m 'restore all'
210 $ hg up null
210 $ hg up null
211 0 files updated, 0 files merged, 14 files removed, 0 files unresolved
211 0 files updated, 0 files merged, 14 files removed, 0 files unresolved
212 $
212 $
213 $ cd ..
213 $ cd ..
214 $ hg -R source-repo debugdeltachain -m
214 $ hg -R source-repo debugdeltachain -m
215 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
215 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
216 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
216 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
217 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
217 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
218 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
218 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
219 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
219 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
220 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
220 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
221 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
221 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
222 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
222 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
223 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
223 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
224 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
224 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
225 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
225 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
226 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
226 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
227 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
227 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
228 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
228 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
229 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
229 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
230 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
230 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
231 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
231 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
232 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
232 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
233 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
233 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
234 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
234 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
235 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
235 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
236 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
236 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
237 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
237 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
238 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
238 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
239 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
239 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
240 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
240 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
241 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
241 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
242 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
242 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
243 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
243 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
244 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
244 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
245 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
245 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
246 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
246 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
247 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
247 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
248 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
248 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
249 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
249 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
250 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
250 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
251 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
251 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
252 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
252 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
253 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
253 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
254 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
254 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
255 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
255 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
256 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
256 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
257 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
257 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
258 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
258 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
259 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
259 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
260 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
260 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
261 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
261 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
262 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
262 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
263 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
263 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
264 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
264 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
265 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000
265 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000
266 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000
266 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000
267 51 4 3 50 prev 356 594 611 1.02862 611 0 0.00000
267 51 4 3 50 prev 356 594 611 1.02862 611 0 0.00000
268 52 4 4 51 p1 58 640 669 1.04531 669 0 0.00000
268 52 4 4 51 p1 58 640 669 1.04531 669 0 0.00000
269 53 5 1 -1 base 0 0 0 0.00000 0 0 0.00000
269 53 5 1 -1 base 0 0 0 0.00000 0 0 0.00000
270 54 6 1 -1 base 369 640 369 0.57656 369 0 0.00000
270 54 6 1 -1 base 369 640 369 0.57656 369 0 0.00000
271 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=2800 relax-chain --config format.generaldelta=yes
271 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=2800 relax-chain --config format.generaldelta=yes
272 requesting all changes
272 requesting all changes
273 adding changesets
273 adding changesets
274 adding manifests
274 adding manifests
275 adding file changes
275 adding file changes
276 added 55 changesets with 53 changes to 53 files (+2 heads)
276 added 55 changesets with 53 changes to 53 files (+2 heads)
277 new changesets 61246295ee1e:c930ac4a5b32
277 new changesets 61246295ee1e:c930ac4a5b32
278 updating to branch default
278 updating to branch default
279 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 $ hg -R relax-chain debugdeltachain -m
280 $ hg -R relax-chain debugdeltachain -m
281 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
281 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
282 0 1 1 -1 base 47 46 47 1.02174 47 0 0.00000
282 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
283 1 1 2 0 p1 58 92 105 1.14130 105 0 0.00000
283 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
284 2 1 3 1 p1 58 138 163 1.18116 163 0 0.00000
284 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
285 3 1 4 2 p1 58 184 221 1.20109 221 0 0.00000
285 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
286 4 1 5 3 p1 58 230 279 1.21304 279 0 0.00000
286 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
287 5 1 6 4 p1 58 276 337 1.22101 337 0 0.00000
287 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
288 6 1 7 5 p1 58 322 395 1.22671 395 0 0.00000
288 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
289 7 1 8 6 p1 58 368 453 1.23098 453 0 0.00000
289 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
290 8 1 9 7 p1 58 414 511 1.23430 511 0 0.00000
290 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
291 9 1 10 8 p1 58 460 569 1.23696 569 0 0.00000
291 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
292 10 1 11 9 p1 58 506 627 1.23913 627 0 0.00000
292 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
293 11 1 12 10 p1 58 552 685 1.24094 685 0 0.00000
293 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
294 12 1 13 11 p1 58 598 743 1.24247 743 0 0.00000
294 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
295 13 1 14 12 p1 58 644 801 1.24379 801 0 0.00000
295 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
296 14 1 15 13 p1 58 690 859 1.24493 859 0 0.00000
296 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
297 15 1 16 14 p1 58 736 917 1.24592 917 0 0.00000
297 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
298 16 1 17 15 p1 58 782 975 1.24680 975 0 0.00000
298 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
299 17 1 18 16 p1 58 828 1033 1.24758 1033 0 0.00000
299 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
300 18 1 19 17 p1 58 874 1091 1.24828 1091 0 0.00000
300 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
301 19 1 20 18 p1 58 920 1149 1.24891 1149 0 0.00000
301 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
302 20 1 21 19 p1 58 966 1207 1.24948 1207 0 0.00000
302 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
303 21 1 22 20 p1 58 1012 1265 1.25000 1265 0 0.00000
303 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
304 22 1 23 21 p1 58 1058 1323 1.25047 1323 0 0.00000
304 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
305 23 1 24 22 p1 58 1104 1381 1.25091 1381 0 0.00000
305 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
306 24 1 25 23 p1 58 1150 1439 1.25130 1439 0 0.00000
306 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
307 25 1 26 24 p1 58 1196 1497 1.25167 1497 0 0.00000
307 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
308 26 1 27 25 p1 58 1242 1555 1.25201 1555 0 0.00000
308 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
309 27 1 28 26 p1 58 1288 1613 1.25233 1613 0 0.00000
309 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
310 28 1 29 27 p1 58 1334 1671 1.25262 1671 0 0.00000
310 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
311 29 1 30 28 p1 58 1380 1729 1.25290 1729 0 0.00000
311 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
312 30 1 31 29 p1 58 1426 1787 1.25316 1787 0 0.00000
312 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
313 31 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
313 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
314 32 2 2 31 p1 57 90 103 1.14444 103 0 0.00000
314 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
315 33 2 3 32 p1 57 135 160 1.18519 160 0 0.00000
315 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
316 34 2 4 33 p1 57 180 217 1.20556 217 0 0.00000
316 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
317 35 2 5 34 p1 57 225 274 1.21778 274 0 0.00000
317 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
318 36 2 6 35 p1 57 270 331 1.22593 331 0 0.00000
318 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
319 37 2 7 36 p1 58 316 389 1.23101 389 0 0.00000
319 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
320 38 2 8 37 p1 58 362 447 1.23481 447 0 0.00000
320 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
321 39 3 1 -1 base 46 45 46 1.02222 46 0 0.00000
321 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
322 40 3 2 39 p1 57 90 103 1.14444 103 0 0.00000
322 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
323 41 3 3 40 p1 57 135 160 1.18519 160 0 0.00000
323 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
324 42 3 4 41 p1 57 180 217 1.20556 217 0 0.00000
324 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
325 43 3 5 42 p1 58 226 275 1.21681 275 0 0.00000
325 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
326 44 3 6 43 p1 58 272 333 1.22426 333 0 0.00000
326 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
327 45 3 7 44 p1 58 318 391 1.22956 391 0 0.00000
327 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
328 46 3 8 45 p1 58 364 449 1.23352 449 0 0.00000
328 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
329 47 3 9 46 p1 58 410 507 1.23659 507 0 0.00000
329 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
330 48 3 10 47 p1 58 456 565 1.23904 565 0 0.00000
330 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
331 49 3 11 48 p1 58 502 623 1.24104 623 0 0.00000
331 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000
332 50 3 12 49 p1 58 548 681 1.24270 681 0 0.00000
332 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000
333 51 3 13 50 p1 58 594 739 1.24411 739 0 0.00000
333 51 2 13 17 p1 58 594 739 1.24411 2781 2042 2.76319
334 52 3 14 51 p1 58 640 797 1.24531 797 0 0.00000
334 52 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
335 53 4 1 -1 base 0 0 0 0.00000 0 0 0.00000
335 53 6 1 -1 base 0 0 0 0.00000 0 0 0.00000
336 54 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
336 54 7 1 -1 base 369 640 369 0.57656 369 0 0.00000
337 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=0 noconst-chain --config format.generaldelta=yes
337 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=0 noconst-chain --config format.generaldelta=yes
338 requesting all changes
338 requesting all changes
339 adding changesets
339 adding changesets
340 adding manifests
340 adding manifests
341 adding file changes
341 adding file changes
342 added 55 changesets with 53 changes to 53 files (+2 heads)
342 added 55 changesets with 53 changes to 53 files (+2 heads)
343 new changesets 61246295ee1e:c930ac4a5b32
343 new changesets 61246295ee1e:c930ac4a5b32
344 updating to branch default
344 updating to branch default
345 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
345 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
346 $ hg -R noconst-chain debugdeltachain -m
346 $ hg -R noconst-chain debugdeltachain -m
347 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
347 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
348 0 1 1 -1 base 47 46 47 1.02174 47 0 0.00000
348 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
349 1 1 2 0 p1 58 92 105 1.14130 105 0 0.00000
349 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
350 2 1 3 1 p1 58 138 163 1.18116 163 0 0.00000
350 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
351 3 1 4 2 p1 58 184 221 1.20109 221 0 0.00000
351 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
352 4 1 5 3 p1 58 230 279 1.21304 279 0 0.00000
352 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
353 5 1 6 4 p1 58 276 337 1.22101 337 0 0.00000
353 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
354 6 1 7 5 p1 58 322 395 1.22671 395 0 0.00000
354 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
355 7 1 8 6 p1 58 368 453 1.23098 453 0 0.00000
355 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
356 8 1 9 7 p1 58 414 511 1.23430 511 0 0.00000
356 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
357 9 1 10 8 p1 58 460 569 1.23696 569 0 0.00000
357 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
358 10 1 11 9 p1 58 506 627 1.23913 627 0 0.00000
358 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
359 11 1 12 10 p1 58 552 685 1.24094 685 0 0.00000
359 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
360 12 1 13 11 p1 58 598 743 1.24247 743 0 0.00000
360 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
361 13 1 14 12 p1 58 644 801 1.24379 801 0 0.00000
361 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
362 14 1 15 13 p1 58 690 859 1.24493 859 0 0.00000
362 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
363 15 1 16 14 p1 58 736 917 1.24592 917 0 0.00000
363 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
364 16 1 17 15 p1 58 782 975 1.24680 975 0 0.00000
364 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
365 17 1 18 16 p1 58 828 1033 1.24758 1033 0 0.00000
365 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
366 18 1 19 17 p1 58 874 1091 1.24828 1091 0 0.00000
366 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
367 19 1 20 18 p1 58 920 1149 1.24891 1149 0 0.00000
367 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
368 20 1 21 19 p1 58 966 1207 1.24948 1207 0 0.00000
368 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
369 21 1 22 20 p1 58 1012 1265 1.25000 1265 0 0.00000
369 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
370 22 1 23 21 p1 58 1058 1323 1.25047 1323 0 0.00000
370 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
371 23 1 24 22 p1 58 1104 1381 1.25091 1381 0 0.00000
371 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
372 24 1 25 23 p1 58 1150 1439 1.25130 1439 0 0.00000
372 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
373 25 1 26 24 p1 58 1196 1497 1.25167 1497 0 0.00000
373 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
374 26 1 27 25 p1 58 1242 1555 1.25201 1555 0 0.00000
374 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
375 27 1 28 26 p1 58 1288 1613 1.25233 1613 0 0.00000
375 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
376 28 1 29 27 p1 58 1334 1671 1.25262 1671 0 0.00000
376 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
377 29 1 30 28 p1 58 1380 1729 1.25290 1729 0 0.00000
377 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
378 30 1 31 29 p1 58 1426 1787 1.25316 1787 0 0.00000
378 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
379 31 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
379 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
380 32 2 2 31 p1 57 90 103 1.14444 103 0 0.00000
380 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
381 33 2 3 32 p1 57 135 160 1.18519 160 0 0.00000
381 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
382 34 2 4 33 p1 57 180 217 1.20556 217 0 0.00000
382 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
383 35 2 5 34 p1 57 225 274 1.21778 274 0 0.00000
383 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
384 36 2 6 35 p1 57 270 331 1.22593 331 0 0.00000
384 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
385 37 2 7 36 p1 58 316 389 1.23101 389 0 0.00000
385 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
386 38 2 8 37 p1 58 362 447 1.23481 447 0 0.00000
386 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
387 39 3 1 -1 base 46 45 46 1.02222 46 0 0.00000
387 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
388 40 3 2 39 p1 57 90 103 1.14444 103 0 0.00000
388 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
389 41 3 3 40 p1 57 135 160 1.18519 160 0 0.00000
389 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
390 42 3 4 41 p1 57 180 217 1.20556 217 0 0.00000
390 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
391 43 3 5 42 p1 58 226 275 1.21681 275 0 0.00000
391 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
392 44 3 6 43 p1 58 272 333 1.22426 333 0 0.00000
392 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
393 45 3 7 44 p1 58 318 391 1.22956 391 0 0.00000
393 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
394 46 3 8 45 p1 58 364 449 1.23352 449 0 0.00000
394 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
395 47 3 9 46 p1 58 410 507 1.23659 507 0 0.00000
395 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
396 48 3 10 47 p1 58 456 565 1.23904 565 0 0.00000
396 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
397 49 3 11 48 p1 58 502 623 1.24104 623 0 0.00000
397 49 1 7 5 p1 58 316 389 1.23101 2857 2468 6.34447
398 50 3 12 49 p1 58 548 681 1.24270 681 0 0.00000
398 50 1 8 49 p1 58 362 447 1.23481 2915 2468 5.52125
399 51 3 13 50 p1 58 594 739 1.24411 739 0 0.00000
399 51 2 13 17 p1 58 594 739 1.24411 2642 1903 2.57510
400 52 3 14 51 p1 58 640 797 1.24531 797 0 0.00000
400 52 2 14 51 p1 58 640 797 1.24531 2700 1903 2.38770
401 53 4 1 -1 base 0 0 0 0.00000 0 0 0.00000
401 53 4 1 -1 base 0 0 0 0.00000 0 0 0.00000
402 54 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
402 54 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
General Comments 0
You need to be logged in to leave comments. Login now