##// END OF EJS Templates
sidedata-exchange: rewrite sidedata on-the-fly whenever possible...
Raphaël Gomès -
r47452:ba8e508a default
parent child Browse files
Show More
@@ -0,0 +1,473 b''
1 ===========================
2 Tests for sidedata exchange
3 ===========================
4
5 Check simple exchange behavior
6 ==============================
7
8 Pusher and pushed have sidedata enabled
9 ---------------------------------------
10
11 $ hg init sidedata-source --config format.exp-use-side-data=yes
12 $ cat << EOF >> sidedata-source/.hg/hgrc
13 > [extensions]
14 > testsidedata=$TESTDIR/testlib/ext-sidedata-5.py
15 > EOF
16 $ hg init sidedata-target --config format.exp-use-side-data=yes
17 $ cat << EOF >> sidedata-target/.hg/hgrc
18 > [extensions]
19 > testsidedata=$TESTDIR/testlib/ext-sidedata-5.py
20 > EOF
21 $ cd sidedata-source
22 $ echo a > a
23 $ echo b > b
24 $ echo c > c
25 $ hg commit -Am "initial"
26 adding a
27 adding b
28 adding c
29 $ echo aa > a
30 $ hg commit -m "other"
31 $ hg push -r . ../sidedata-target
32 pushing to ../sidedata-target
33 searching for changes
34 adding changesets
35 adding manifests
36 adding file changes
37 added 2 changesets with 4 changes to 3 files
38 $ hg -R ../sidedata-target debugsidedata -c 0
39 2 sidedata entries
40 entry-0001 size 4
41 entry-0002 size 32
42 $ hg -R ../sidedata-target debugsidedata -c 1 -v
43 2 sidedata entries
44 entry-0001 size 4
45 '\x00\x00\x00:'
46 entry-0002 size 32
47 '\xa3\xee4v\x99\x85$\x9f\x1f\x8dKe\x0f\xc3\x9d-\xc9\xb5%[\x15=h\xe9\xf2O\xb5\xd9\x1f*\xff\xe5'
48 $ hg -R ../sidedata-target debugsidedata -m 0
49 2 sidedata entries
50 entry-0001 size 4
51 entry-0002 size 32
52 $ hg -R ../sidedata-target debugsidedata -m 1 -v
53 2 sidedata entries
54 entry-0001 size 4
55 '\x00\x00\x00\x81'
56 entry-0002 size 32
57 '-bL\xc5\xa4uu"#\xac\x1b`,\xc0\xbc\x9d\xf5\xac\xf0\x1d\x89)2\xf8N\xb1\x14m\xce\xd7\xbc\xae'
58 $ hg -R ../sidedata-target debugsidedata a 0
59 2 sidedata entries
60 entry-0001 size 4
61 entry-0002 size 32
62 $ hg -R ../sidedata-target debugsidedata a 1 -v
63 2 sidedata entries
64 entry-0001 size 4
65 '\x00\x00\x00\x03'
66 entry-0002 size 32
67 '\xd9\xcd\x81UvL5C\xf1\x0f\xad\x8aH\rt17Fo\x8dU!<\x8e\xae\xfc\xd1/\x06\xd4:\x80'
68 $ cd ..
69
70 Puller and pulled have sidedata enabled
71 ---------------------------------------
72
73 $ rm -rf sidedata-source sidedata-target
74 $ hg init sidedata-source --config format.exp-use-side-data=yes
75 $ cat << EOF >> sidedata-source/.hg/hgrc
76 > [extensions]
77 > testsidedata=$TESTDIR/testlib/ext-sidedata-5.py
78 > EOF
79 $ hg init sidedata-target --config format.exp-use-side-data=yes
80 $ cat << EOF >> sidedata-target/.hg/hgrc
81 > [extensions]
82 > testsidedata=$TESTDIR/testlib/ext-sidedata-5.py
83 > EOF
84 $ cd sidedata-source
85 $ echo a > a
86 $ echo b > b
87 $ echo c > c
88 $ hg commit -Am "initial"
89 adding a
90 adding b
91 adding c
92 $ echo aa > a
93 $ hg commit -m "other"
94 $ hg pull -R ../sidedata-target ../sidedata-source
95 pulling from ../sidedata-source
96 requesting all changes
97 adding changesets
98 adding manifests
99 adding file changes
100 added 2 changesets with 4 changes to 3 files
101 new changesets 05da661850d7:7ec8b4049447
102 (run 'hg update' to get a working copy)
103 $ hg -R ../sidedata-target debugsidedata -c 0
104 2 sidedata entries
105 entry-0001 size 4
106 entry-0002 size 32
107 $ hg -R ../sidedata-target debugsidedata -c 1 -v
108 2 sidedata entries
109 entry-0001 size 4
110 '\x00\x00\x00:'
111 entry-0002 size 32
112 '\xa3\xee4v\x99\x85$\x9f\x1f\x8dKe\x0f\xc3\x9d-\xc9\xb5%[\x15=h\xe9\xf2O\xb5\xd9\x1f*\xff\xe5'
113 $ hg -R ../sidedata-target debugsidedata -m 0
114 2 sidedata entries
115 entry-0001 size 4
116 entry-0002 size 32
117 $ hg -R ../sidedata-target debugsidedata -m 1 -v
118 2 sidedata entries
119 entry-0001 size 4
120 '\x00\x00\x00\x81'
121 entry-0002 size 32
122 '-bL\xc5\xa4uu"#\xac\x1b`,\xc0\xbc\x9d\xf5\xac\xf0\x1d\x89)2\xf8N\xb1\x14m\xce\xd7\xbc\xae'
123 $ hg -R ../sidedata-target debugsidedata a 0
124 2 sidedata entries
125 entry-0001 size 4
126 entry-0002 size 32
127 $ hg -R ../sidedata-target debugsidedata a 1 -v
128 2 sidedata entries
129 entry-0001 size 4
130 '\x00\x00\x00\x03'
131 entry-0002 size 32
132 '\xd9\xcd\x81UvL5C\xf1\x0f\xad\x8aH\rt17Fo\x8dU!<\x8e\xae\xfc\xd1/\x06\xd4:\x80'
133 $ cd ..
134
135 Now on to asymmetric configs.
136
137 Pusher has sidedata enabled, pushed does not
138 --------------------------------------------
139
140 $ rm -rf sidedata-source sidedata-target
141 $ hg init sidedata-source --config format.exp-use-side-data=yes
142 $ cat << EOF >> sidedata-source/.hg/hgrc
143 > [extensions]
144 > testsidedata=$TESTDIR/testlib/ext-sidedata-5.py
145 > EOF
146 $ hg init sidedata-target --config format.exp-use-side-data=no
147 $ cd sidedata-source
148 $ echo a > a
149 $ echo b > b
150 $ echo c > c
151 $ hg commit -Am "initial"
152 adding a
153 adding b
154 adding c
155 $ echo aa > a
156 $ hg commit -m "other"
157 $ hg push -r . ../sidedata-target --traceback
158 pushing to ../sidedata-target
159 searching for changes
160 adding changesets
161 adding manifests
162 adding file changes
163 added 2 changesets with 4 changes to 3 files
164 $ hg -R ../sidedata-target log -G
165 o changeset: 1:7ec8b4049447
166 | tag: tip
167 | user: test
168 | date: Thu Jan 01 00:00:00 1970 +0000
169 | summary: other
170 |
171 o changeset: 0:05da661850d7
172 user: test
173 date: Thu Jan 01 00:00:00 1970 +0000
174 summary: initial
175
176
177 $ hg -R ../sidedata-target debugsidedata -c 0
178 $ hg -R ../sidedata-target debugsidedata -c 1 -v
179 $ hg -R ../sidedata-target debugsidedata -m 0
180 $ hg -R ../sidedata-target debugsidedata -m 1 -v
181 $ hg -R ../sidedata-target debugsidedata a 0
182 $ hg -R ../sidedata-target debugsidedata a 1 -v
183 $ cd ..
184
185 Pulled has sidedata enabled, puller does not
186 --------------------------------------------
187
188 $ rm -rf sidedata-source sidedata-target
189 $ hg init sidedata-source --config format.exp-use-side-data=yes
190 $ cat << EOF >> sidedata-source/.hg/hgrc
191 > [extensions]
192 > testsidedata=$TESTDIR/testlib/ext-sidedata-5.py
193 > EOF
194 $ hg init sidedata-target --config format.exp-use-side-data=no
195 $ cd sidedata-source
196 $ echo a > a
197 $ echo b > b
198 $ echo c > c
199 $ hg commit -Am "initial"
200 adding a
201 adding b
202 adding c
203 $ echo aa > a
204 $ hg commit -m "other"
205 $ hg pull -R ../sidedata-target ../sidedata-source
206 pulling from ../sidedata-source
207 requesting all changes
208 adding changesets
209 adding manifests
210 adding file changes
211 added 2 changesets with 4 changes to 3 files
212 new changesets 05da661850d7:7ec8b4049447
213 (run 'hg update' to get a working copy)
214 $ hg -R ../sidedata-target log -G
215 o changeset: 1:7ec8b4049447
216 | tag: tip
217 | user: test
218 | date: Thu Jan 01 00:00:00 1970 +0000
219 | summary: other
220 |
221 o changeset: 0:05da661850d7
222 user: test
223 date: Thu Jan 01 00:00:00 1970 +0000
224 summary: initial
225
226
227 $ hg -R ../sidedata-target debugsidedata -c 0
228 $ hg -R ../sidedata-target debugsidedata -c 1 -v
229 $ hg -R ../sidedata-target debugsidedata -m 0
230 $ hg -R ../sidedata-target debugsidedata -m 1 -v
231 $ hg -R ../sidedata-target debugsidedata a 0
232 $ hg -R ../sidedata-target debugsidedata a 1 -v
233 $ cd ..
234
235
236 Check sidedata exchange with on-the-fly generation and removal
237 ==============================================================
238
239 (Push) Target has strict superset of the source
240 -----------------------------------------------
241
242 $ hg init source-repo --config format.exp-use-side-data=yes
243 $ hg init target-repo --config format.exp-use-side-data=yes
244 $ cat << EOF >> target-repo/.hg/hgrc
245 > [extensions]
246 > testsidedata=$TESTDIR/testlib/ext-sidedata.py
247 > EOF
248 $ cd source-repo
249 $ echo aaa > a
250 $ hg add a
251 $ hg commit -m a
252 $ echo aaa > b
253 $ hg add b
254 $ hg commit -m b
255 $ echo xxx >> a
256 $ hg commit -m aa
257
258 No sidedata is generated in the source
259 $ hg debugsidedata -c 0
260
261 Check that sidedata capabilities are advertised
262 $ hg debugcapabilities ../target-repo | grep sidedata
263 exp-wanted-sidedata=1,2
264
265 We expect the client to abort the push since it's not capable of generating
266 what the server is asking
267 $ hg push -r . ../target-repo
268 pushing to ../target-repo
269 abort: cannot push: required sidedata category not supported by this client: '1'
270 [255]
271
272 Add the required capabilities
273 $ cat << EOF >> .hg/hgrc
274 > [extensions]
275 > testsidedata2=$TESTDIR/testlib/ext-sidedata-2.py
276 > EOF
277
278 We expect the target to have sidedata that was generated by the source on push
279 $ hg push -r . ../target-repo
280 pushing to ../target-repo
281 searching for changes
282 adding changesets
283 adding manifests
284 adding file changes
285 added 3 changesets with 3 changes to 2 files
286 $ cd ../target-repo
287 $ hg debugsidedata -c 0
288 2 sidedata entries
289 entry-0001 size 4
290 entry-0002 size 32
291 $ hg debugsidedata -c 1 -v
292 2 sidedata entries
293 entry-0001 size 4
294 '\x00\x00\x006'
295 entry-0002 size 32
296 '\x98\t\xf9\xc4v\xf0\xc5P\x90\xf7wRf\xe8\xe27e\xfc\xc1\x93\xa4\x96\xd0\x1d\x97\xaaG\x1d\xd7t\xfa\xde'
297 $ hg debugsidedata -m 2
298 2 sidedata entries
299 entry-0001 size 4
300 entry-0002 size 32
301 $ hg debugsidedata a 1
302 2 sidedata entries
303 entry-0001 size 4
304 entry-0002 size 32
305 $ cd ..
306
307 (Push) Difference is not subset/superset
308 ----------------------------------------
309
310 Source has one in common, one missing and one more sidedata category with the
311 target.
312
313 $ rm -rf source-repo target-repo
314 $ hg init source-repo --config format.exp-use-side-data=yes
315 $ cat << EOF >> source-repo/.hg/hgrc
316 > [extensions]
317 > testsidedata3=$TESTDIR/testlib/ext-sidedata-3.py
318 > EOF
319 $ hg init target-repo --config format.exp-use-side-data=yes
320 $ cat << EOF >> target-repo/.hg/hgrc
321 > [extensions]
322 > testsidedata4=$TESTDIR/testlib/ext-sidedata-4.py
323 > EOF
324 $ cd source-repo
325 $ echo aaa > a
326 $ hg add a
327 $ hg commit -m a
328 $ echo aaa > b
329 $ hg add b
330 $ hg commit -m b
331 $ echo xxx >> a
332 $ hg commit -m aa
333
334 Check that sidedata capabilities are advertised
335 $ hg debugcapabilities . | grep sidedata
336 exp-wanted-sidedata=1,2
337 $ hg debugcapabilities ../target-repo | grep sidedata
338 exp-wanted-sidedata=2,3
339
340 Sidedata is generated in the source, but only the right categories (entry-0001 and entry-0002)
341 $ hg debugsidedata -c 0
342 2 sidedata entries
343 entry-0001 size 4
344 entry-0002 size 32
345 $ hg debugsidedata -c 1 -v
346 2 sidedata entries
347 entry-0001 size 4
348 '\x00\x00\x006'
349 entry-0002 size 32
350 '\x98\t\xf9\xc4v\xf0\xc5P\x90\xf7wRf\xe8\xe27e\xfc\xc1\x93\xa4\x96\xd0\x1d\x97\xaaG\x1d\xd7t\xfa\xde'
351 $ hg debugsidedata -m 2
352 2 sidedata entries
353 entry-0001 size 4
354 entry-0002 size 32
355 $ hg debugsidedata a 1
356 2 sidedata entries
357 entry-0001 size 4
358 entry-0002 size 32
359
360
361 We expect the target to have sidedata that was generated by the source on push,
362 and also removed the sidedata categories that are not supported by the target.
363 Namely, we expect entry-0002 (only exchanged) and entry-0003 (generated),
364 but not entry-0001.
365
366 $ hg push -r . ../target-repo --traceback
367 pushing to ../target-repo
368 searching for changes
369 adding changesets
370 adding manifests
371 adding file changes
372 added 3 changesets with 3 changes to 2 files
373 $ cd ../target-repo
374 $ hg log -G
375 o changeset: 2:40f977031323
376 | tag: tip
377 | user: test
378 | date: Thu Jan 01 00:00:00 1970 +0000
379 | summary: aa
380 |
381 o changeset: 1:2707720c6597
382 | user: test
383 | date: Thu Jan 01 00:00:00 1970 +0000
384 | summary: b
385 |
386 o changeset: 0:7049e48789d7
387 user: test
388 date: Thu Jan 01 00:00:00 1970 +0000
389 summary: a
390
391 $ hg debugsidedata -c 0
392 2 sidedata entries
393 entry-0002 size 32
394 entry-0003 size 48
395 $ hg debugsidedata -c 1 -v
396 2 sidedata entries
397 entry-0002 size 32
398 '\x98\t\xf9\xc4v\xf0\xc5P\x90\xf7wRf\xe8\xe27e\xfc\xc1\x93\xa4\x96\xd0\x1d\x97\xaaG\x1d\xd7t\xfa\xde'
399 entry-0003 size 48
400 '\x87\xcf\xdfI/\xb5\xed\xeaC\xc1\xf0S\xf3X\x1c\xcc\x00m\xee\xe6#\xc1\xe3\xcaB8Fk\x82e\xfc\xc01\xf6\xb7\xb9\xb3([\xf6D\xa6\xcf\x9b\xea\x11{\x08'
401 $ hg debugsidedata -m 2
402 2 sidedata entries
403 entry-0002 size 32
404 entry-0003 size 48
405 $ hg debugsidedata a 1
406 2 sidedata entries
407 entry-0002 size 32
408 entry-0003 size 48
409 $ cd ..
410
411 (Pull) Target has strict superset of the source
412 -----------------------------------------------
413
414 $ rm -rf source-repo target-repo
415 $ hg init source-repo --config format.exp-use-side-data=yes
416 $ hg init target-repo --config format.exp-use-side-data=yes
417 $ cat << EOF >> target-repo/.hg/hgrc
418 > [extensions]
419 > testsidedata=$TESTDIR/testlib/ext-sidedata.py
420 > EOF
421 $ cd source-repo
422 $ echo aaa > a
423 $ hg add a
424 $ hg commit -m a
425 $ echo aaa > b
426 $ hg add b
427 $ hg commit -m b
428 $ echo xxx >> a
429 $ hg commit -m aa
430
431 No sidedata is generated in the source
432 $ hg debugsidedata -c 0
433
434 Check that sidedata capabilities are advertised
435 $ hg debugcapabilities ../target-repo | grep sidedata
436 exp-wanted-sidedata=1,2
437
438 $ cd ../target-repo
439
440 Add the required capabilities
441 $ cat << EOF >> .hg/hgrc
442 > [extensions]
443 > testsidedata2=$TESTDIR/testlib/ext-sidedata-2.py
444 > EOF
445
446 We expect the target to have sidedata that it generated on-the-fly during pull
447 $ hg pull -r . ../source-repo --traceback
448 pulling from ../source-repo
449 adding changesets
450 adding manifests
451 adding file changes
452 added 3 changesets with 3 changes to 2 files
453 new changesets 7049e48789d7:40f977031323
454 (run 'hg update' to get a working copy)
455 $ hg debugsidedata -c 0 --traceback
456 2 sidedata entries
457 entry-0001 size 4
458 entry-0002 size 32
459 $ hg debugsidedata -c 1 -v --traceback
460 2 sidedata entries
461 entry-0001 size 4
462 '\x00\x00\x006'
463 entry-0002 size 32
464 '\x98\t\xf9\xc4v\xf0\xc5P\x90\xf7wRf\xe8\xe27e\xfc\xc1\x93\xa4\x96\xd0\x1d\x97\xaaG\x1d\xd7t\xfa\xde'
465 $ hg debugsidedata -m 2
466 2 sidedata entries
467 entry-0001 size 4
468 entry-0002 size 32
469 $ hg debugsidedata a 1
470 2 sidedata entries
471 entry-0001 size 4
472 entry-0002 size 32
473 $ cd ..
@@ -0,0 +1,81 b''
1 # coding: utf8
2 # ext-sidedata-5.py - small extension to test (differently still) the sidedata
3 # logic
4 #
5 # Simulates a server for a simple sidedata exchange.
6 #
7 # Copyright 2021 Raphaël Gomès <rgomes@octobus.net>
8 #
9 # This software may be used and distributed according to the terms of the
10 # GNU General Public License version 2 or any later version.
11
12 from __future__ import absolute_import
13
14 import hashlib
15 import struct
16
17 from mercurial import (
18 extensions,
19 revlog,
20 )
21
22
23 from mercurial.revlogutils import sidedata as sidedatamod
24
25
26 def compute_sidedata_1(repo, revlog, rev, sidedata, text=None):
27 sidedata = sidedata.copy()
28 if text is None:
29 text = revlog.revision(rev)
30 sidedata[sidedatamod.SD_TEST1] = struct.pack('>I', len(text))
31 return sidedata
32
33
34 def compute_sidedata_2(repo, revlog, rev, sidedata, text=None):
35 sidedata = sidedata.copy()
36 if text is None:
37 text = revlog.revision(rev)
38 sha256 = hashlib.sha256(text).digest()
39 sidedata[sidedatamod.SD_TEST2] = struct.pack('>32s', sha256)
40 return sidedata
41
42
43 def reposetup(ui, repo):
44 # Sidedata keys happen to be the same as the categories, easier for testing.
45 for kind in (b'changelog', b'manifest', b'filelog'):
46 repo.register_sidedata_computer(
47 kind,
48 sidedatamod.SD_TEST1,
49 (sidedatamod.SD_TEST1,),
50 compute_sidedata_1,
51 )
52 repo.register_sidedata_computer(
53 kind,
54 sidedatamod.SD_TEST2,
55 (sidedatamod.SD_TEST2,),
56 compute_sidedata_2,
57 )
58
59 # We don't register sidedata computers because we don't care within these
60 # tests
61 repo.register_wanted_sidedata(sidedatamod.SD_TEST1)
62 repo.register_wanted_sidedata(sidedatamod.SD_TEST2)
63
64
65 def wrapaddrevision(
66 orig, self, text, transaction, link, p1, p2, *args, **kwargs
67 ):
68 if kwargs.get('sidedata') is None:
69 kwargs['sidedata'] = {}
70 sd = kwargs['sidedata']
71 ## let's store some arbitrary data just for testing
72 # text length
73 sd[sidedatamod.SD_TEST1] = struct.pack('>I', len(text))
74 # and sha2 hashes
75 sha256 = hashlib.sha256(text).digest()
76 sd[sidedatamod.SD_TEST2] = struct.pack('>32s', sha256)
77 return orig(self, text, transaction, link, p1, p2, *args, **kwargs)
78
79
80 def extsetup(ui):
81 extensions.wrapfunction(revlog.revlog, 'addrevision', wrapaddrevision)
@@ -7,6 +7,7 b''
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import collections
10 import os
11 import os
11 import struct
12 import struct
12 import weakref
13 import weakref
@@ -252,7 +253,7 b' class cg1unpacker(object):'
252 pos = next
253 pos = next
253 yield closechunk()
254 yield closechunk()
254
255
255 def _unpackmanifests(self, repo, revmap, trp, prog):
256 def _unpackmanifests(self, repo, revmap, trp, prog, addrevisioncb=None):
256 self.callback = prog.increment
257 self.callback = prog.increment
257 # no need to check for empty manifest group here:
258 # no need to check for empty manifest group here:
258 # if the result of the merge of 1 and 2 is the same in 3 and 4,
259 # if the result of the merge of 1 and 2 is the same in 3 and 4,
@@ -260,7 +261,8 b' class cg1unpacker(object):'
260 # be empty during the pull
261 # be empty during the pull
261 self.manifestheader()
262 self.manifestheader()
262 deltas = self.deltaiter()
263 deltas = self.deltaiter()
263 repo.manifestlog.getstorage(b'').addgroup(deltas, revmap, trp)
264 storage = repo.manifestlog.getstorage(b'')
265 storage.addgroup(deltas, revmap, trp, addrevisioncb=addrevisioncb)
264 prog.complete()
266 prog.complete()
265 self.callback = None
267 self.callback = None
266
268
@@ -369,6 +371,13 b' class cg1unpacker(object):'
369 efilesset = None
371 efilesset = None
370 self.callback = None
372 self.callback = None
371
373
374 # Keep track of the (non-changelog) revlogs we've updated and their
375 # range of new revisions for sidedata rewrite.
376 # TODO do something more efficient than keeping the reference to
377 # the revlogs, especially memory-wise.
378 touched_manifests = {}
379 touched_filelogs = {}
380
372 # pull off the manifest group
381 # pull off the manifest group
373 repo.ui.status(_(b"adding manifests\n"))
382 repo.ui.status(_(b"adding manifests\n"))
374 # We know that we'll never have more manifests than we had
383 # We know that we'll never have more manifests than we had
@@ -376,7 +385,24 b' class cg1unpacker(object):'
376 progress = repo.ui.makeprogress(
385 progress = repo.ui.makeprogress(
377 _(b'manifests'), unit=_(b'chunks'), total=changesets
386 _(b'manifests'), unit=_(b'chunks'), total=changesets
378 )
387 )
379 self._unpackmanifests(repo, revmap, trp, progress)
388 on_manifest_rev = None
389 if sidedata_helpers and b'manifest' in sidedata_helpers[1]:
390
391 def on_manifest_rev(manifest, rev):
392 range = touched_manifests.get(manifest)
393 if not range:
394 touched_manifests[manifest] = (rev, rev)
395 else:
396 assert rev == range[1] + 1
397 touched_manifests[manifest] = (range[0], rev)
398
399 self._unpackmanifests(
400 repo,
401 revmap,
402 trp,
403 progress,
404 addrevisioncb=on_manifest_rev,
405 )
380
406
381 needfiles = {}
407 needfiles = {}
382 if repo.ui.configbool(b'server', b'validate'):
408 if repo.ui.configbool(b'server', b'validate'):
@@ -390,12 +416,37 b' class cg1unpacker(object):'
390 for f, n in pycompat.iteritems(mfest):
416 for f, n in pycompat.iteritems(mfest):
391 needfiles.setdefault(f, set()).add(n)
417 needfiles.setdefault(f, set()).add(n)
392
418
419 on_filelog_rev = None
420 if sidedata_helpers and b'filelog' in sidedata_helpers[1]:
421
422 def on_filelog_rev(filelog, rev):
423 range = touched_filelogs.get(filelog)
424 if not range:
425 touched_filelogs[filelog] = (rev, rev)
426 else:
427 assert rev == range[1] + 1
428 touched_filelogs[filelog] = (range[0], rev)
429
393 # process the files
430 # process the files
394 repo.ui.status(_(b"adding file changes\n"))
431 repo.ui.status(_(b"adding file changes\n"))
395 newrevs, newfiles = _addchangegroupfiles(
432 newrevs, newfiles = _addchangegroupfiles(
396 repo, self, revmap, trp, efiles, needfiles
433 repo,
434 self,
435 revmap,
436 trp,
437 efiles,
438 needfiles,
439 addrevisioncb=on_filelog_rev,
397 )
440 )
398
441
442 if sidedata_helpers:
443 if b'changelog' in sidedata_helpers[1]:
444 cl.rewrite_sidedata(sidedata_helpers, clstart, clend - 1)
445 for mf, (startrev, endrev) in touched_manifests.items():
446 mf.rewrite_sidedata(sidedata_helpers, startrev, endrev)
447 for fl, (startrev, endrev) in touched_filelogs.items():
448 fl.rewrite_sidedata(sidedata_helpers, startrev, endrev)
449
399 # making sure the value exists
450 # making sure the value exists
400 tr.changes.setdefault(b'changegroup-count-changesets', 0)
451 tr.changes.setdefault(b'changegroup-count-changesets', 0)
401 tr.changes.setdefault(b'changegroup-count-revisions', 0)
452 tr.changes.setdefault(b'changegroup-count-revisions', 0)
@@ -559,14 +610,18 b' class cg3unpacker(cg2unpacker):'
559 node, p1, p2, deltabase, cs, flags = headertuple
610 node, p1, p2, deltabase, cs, flags = headertuple
560 return node, p1, p2, deltabase, cs, flags
611 return node, p1, p2, deltabase, cs, flags
561
612
562 def _unpackmanifests(self, repo, revmap, trp, prog):
613 def _unpackmanifests(self, repo, revmap, trp, prog, addrevisioncb=None):
563 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog)
614 super(cg3unpacker, self)._unpackmanifests(
615 repo, revmap, trp, prog, addrevisioncb=addrevisioncb
616 )
564 for chunkdata in iter(self.filelogheader, {}):
617 for chunkdata in iter(self.filelogheader, {}):
565 # If we get here, there are directory manifests in the changegroup
618 # If we get here, there are directory manifests in the changegroup
566 d = chunkdata[b"filename"]
619 d = chunkdata[b"filename"]
567 repo.ui.debug(b"adding %s revisions\n" % d)
620 repo.ui.debug(b"adding %s revisions\n" % d)
568 deltas = self.deltaiter()
621 deltas = self.deltaiter()
569 if not repo.manifestlog.getstorage(d).addgroup(deltas, revmap, trp):
622 if not repo.manifestlog.getstorage(d).addgroup(
623 deltas, revmap, trp, addrevisioncb=addrevisioncb
624 ):
570 raise error.Abort(_(b"received dir revlog group is empty"))
625 raise error.Abort(_(b"received dir revlog group is empty"))
571
626
572
627
@@ -1793,7 +1848,15 b' def makestream('
1793 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1848 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1794
1849
1795
1850
1796 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1851 def _addchangegroupfiles(
1852 repo,
1853 source,
1854 revmap,
1855 trp,
1856 expectedfiles,
1857 needfiles,
1858 addrevisioncb=None,
1859 ):
1797 revisions = 0
1860 revisions = 0
1798 files = 0
1861 files = 0
1799 progress = repo.ui.makeprogress(
1862 progress = repo.ui.makeprogress(
@@ -1808,7 +1871,13 b' def _addchangegroupfiles(repo, source, r'
1808 o = len(fl)
1871 o = len(fl)
1809 try:
1872 try:
1810 deltas = source.deltaiter()
1873 deltas = source.deltaiter()
1811 if not fl.addgroup(deltas, revmap, trp):
1874 added = fl.addgroup(
1875 deltas,
1876 revmap,
1877 trp,
1878 addrevisioncb=addrevisioncb,
1879 )
1880 if not added:
1812 raise error.Abort(_(b"received file revlog group is empty"))
1881 raise error.Abort(_(b"received file revlog group is empty"))
1813 except error.CensoredBaseError as e:
1882 except error.CensoredBaseError as e:
1814 raise error.Abort(_(b"received delta base is censored: %s") % e)
1883 raise error.Abort(_(b"received delta base is censored: %s") % e)
@@ -3205,3 +3205,54 b' class revlog(object):'
3205 )
3205 )
3206
3206
3207 return d
3207 return d
3208
3209 def rewrite_sidedata(self, helpers, startrev, endrev):
3210 if self.version & 0xFFFF != REVLOGV2:
3211 return
3212 # inline are not yet supported because they suffer from an issue when
3213 # rewriting them (since it's not an append-only operation).
3214 # See issue6485.
3215 assert not self._inline
3216 if not helpers[1] and not helpers[2]:
3217 # Nothing to generate or remove
3218 return
3219
3220 new_entries = []
3221 # append the new sidedata
3222 with self._datafp(b'a+') as fp:
3223 # Maybe this bug still exists, see revlog._writeentry
3224 fp.seek(0, os.SEEK_END)
3225 current_offset = fp.tell()
3226 for rev in range(startrev, endrev + 1):
3227 entry = self.index[rev]
3228 new_sidedata = storageutil.run_sidedata_helpers(
3229 store=self,
3230 sidedata_helpers=helpers,
3231 sidedata={},
3232 rev=rev,
3233 )
3234
3235 serialized_sidedata = sidedatautil.serialize_sidedata(
3236 new_sidedata
3237 )
3238 if entry[8] != 0 or entry[9] != 0:
3239 # rewriting entries that already have sidedata is not
3240 # supported yet, because it introduces garbage data in the
3241 # revlog.
3242 msg = "Rewriting existing sidedata is not supported yet"
3243 raise error.Abort(msg)
3244 entry = entry[:8]
3245 entry += (current_offset, len(serialized_sidedata))
3246
3247 fp.write(serialized_sidedata)
3248 new_entries.append(entry)
3249 current_offset += len(serialized_sidedata)
3250
3251 # rewrite the new index entries
3252 with self._indexfp(b'w+') as fp:
3253 fp.seek(startrev * self._io.size)
3254 for i, entry in enumerate(new_entries):
3255 rev = startrev + i
3256 self.index.replace_sidedata_info(rev, entry[8], entry[9])
3257 packed = self._io.packentry(entry, self.node, self.version, rev)
3258 fp.write(packed)
@@ -271,13 +271,12 b' copy information on to the filelog'
271 $ hg ci --amend -m 'copy a to j, v2'
271 $ hg ci --amend -m 'copy a to j, v2'
272 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/*-*-amend.hg (glob)
272 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/*-*-amend.hg (glob)
273 $ hg debugsidedata -c -v -- -1
273 $ hg debugsidedata -c -v -- -1
274 1 sidedata entries (missing-correct-output !)
274 1 sidedata entries
275 entry-0014 size 24 (missing-correct-output !)
275 entry-0014 size 24
276 '\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00aj' (missing-correct-output !)
276 '\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00aj'
277 #endif
277 #endif
278 $ hg showcopies --config experimental.copies.read-from=filelog-only
278 $ hg showcopies --config experimental.copies.read-from=filelog-only
279 a -> j (sidedata missing-correct-output !)
279 a -> j
280 a -> j (no-sidedata !)
281 The entries should be written to extras even if they're empty (so the client
280 The entries should be written to extras even if they're empty (so the client
282 won't have to fall back to reading from filelogs)
281 won't have to fall back to reading from filelogs)
283 $ echo x >> j
282 $ echo x >> j
@@ -355,8 +354,7 b' with no fallback.'
355 saved backup bundle to $TESTTMP/rebase-rename/.hg/strip-backup/*-*-rebase.hg (glob)
354 saved backup bundle to $TESTTMP/rebase-rename/.hg/strip-backup/*-*-rebase.hg (glob)
356 $ hg st --change . --copies
355 $ hg st --change . --copies
357 A b
356 A b
358 a (sidedata missing-correct-output !)
357 a
359 a (no-sidedata !)
360 R a
358 R a
361 $ cd ..
359 $ cd ..
362
360
@@ -1,6 +1,9 b''
1 # ext-sidedata.py - small extension to test the sidedata logic
1 # coding: utf8
2 # ext-sidedata-2.py - small extension to test (differently) the sidedata logic
2 #
3 #
3 # Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net)
4 # Simulates a client for a complex sidedata exchange.
5 #
6 # Copyright 2021 Raphaël Gomès <rgomes@octobus.net>
4 #
7 #
5 # This software may be used and distributed according to the terms of the
8 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
9 # GNU General Public License version 2 or any later version.
@@ -10,79 +13,38 b' from __future__ import absolute_import'
10 import hashlib
13 import hashlib
11 import struct
14 import struct
12
15
13 from mercurial.node import (
16 from mercurial.revlogutils import sidedata as sidedatamod
14 nullid,
15 nullrev,
16 )
17 from mercurial import (
18 extensions,
19 requirements,
20 revlog,
21 )
22
23 from mercurial.upgrade_utils import engine as upgrade_engine
24
25 from mercurial.revlogutils import sidedata
26
17
27
18
28 def wrapaddrevision(
19 def compute_sidedata_1(repo, revlog, rev, sidedata, text=None):
29 orig, self, text, transaction, link, p1, p2, *args, **kwargs
20 sidedata = sidedata.copy()
30 ):
21 if text is None:
31 if kwargs.get('sidedata') is None:
22 text = revlog.revision(rev)
32 kwargs['sidedata'] = {}
23 sidedata[sidedatamod.SD_TEST1] = struct.pack('>I', len(text))
33 sd = kwargs['sidedata']
24 return sidedata
34 ## let's store some arbitrary data just for testing
35 # text length
36 sd[sidedata.SD_TEST1] = struct.pack('>I', len(text))
37 # and sha2 hashes
38 sha256 = hashlib.sha256(text).digest()
39 sd[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
40 return orig(self, text, transaction, link, p1, p2, *args, **kwargs)
41
25
42
26
43 def wrap_revisiondata(orig, self, nodeorrev, *args, **kwargs):
27 def compute_sidedata_2(repo, revlog, rev, sidedata, text=None):
44 text, sd = orig(self, nodeorrev, *args, **kwargs)
28 sidedata = sidedata.copy()
45 if getattr(self, 'sidedatanocheck', False):
29 if text is None:
46 return text, sd
30 text = revlog.revision(rev)
47 if self.version & 0xFFFF != 2:
31 sha256 = hashlib.sha256(text).digest()
48 return text, sd
32 sidedata[sidedatamod.SD_TEST2] = struct.pack('>32s', sha256)
49 if nodeorrev != nullrev and nodeorrev != nullid:
33 return sidedata
50 if len(text) != struct.unpack('>I', sd[sidedata.SD_TEST1])[0]:
51 raise RuntimeError('text size mismatch')
52 expected = sd[sidedata.SD_TEST2]
53 got = hashlib.sha256(text).digest()
54 if got != expected:
55 raise RuntimeError('sha256 mismatch')
56 return text, sd
57
34
58
35
59 def wrapgetsidedatacompanion(orig, srcrepo, dstrepo):
36 def reposetup(ui, repo):
60 sidedatacompanion = orig(srcrepo, dstrepo)
37 # Sidedata keys happen to be the same as the categories, easier for testing.
61 addedreqs = dstrepo.requirements - srcrepo.requirements
38 for kind in (b'changelog', b'manifest', b'filelog'):
62 if requirements.SIDEDATA_REQUIREMENT in addedreqs:
39 repo.register_sidedata_computer(
63 assert sidedatacompanion is None # deal with composition later
40 kind,
64
41 sidedatamod.SD_TEST1,
65 def sidedatacompanion(revlog, rev):
42 (sidedatamod.SD_TEST1,),
66 update = {}
43 compute_sidedata_1,
67 revlog.sidedatanocheck = True
68 try:
69 text = revlog.revision(rev)
70 finally:
71 del revlog.sidedatanocheck
72 ## let's store some arbitrary data just for testing
73 # text length
74 update[sidedata.SD_TEST1] = struct.pack('>I', len(text))
75 # and sha2 hashes
76 sha256 = hashlib.sha256(text).digest()
77 update[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
78 return False, (), update, 0, 0
79
80 return sidedatacompanion
81
82
83 def extsetup(ui):
84 extensions.wrapfunction(revlog.revlog, 'addrevision', wrapaddrevision)
85 extensions.wrapfunction(revlog.revlog, '_revisiondata', wrap_revisiondata)
86 extensions.wrapfunction(
87 upgrade_engine, 'getsidedatacompanion', wrapgetsidedatacompanion
88 )
44 )
45 repo.register_sidedata_computer(
46 kind,
47 sidedatamod.SD_TEST2,
48 (sidedatamod.SD_TEST2,),
49 compute_sidedata_2,
50 )
@@ -1,6 +1,10 b''
1 # ext-sidedata.py - small extension to test the sidedata logic
1 # coding: utf8
2 # ext-sidedata-3.py - small extension to test (differently still) the sidedata
3 # logic
2 #
4 #
3 # Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net)
5 # Simulates a client for a complex sidedata exchange.
6 #
7 # Copyright 2021 Raphaël Gomès <rgomes@octobus.net>
4 #
8 #
5 # This software may be used and distributed according to the terms of the
9 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
10 # GNU General Public License version 2 or any later version.
@@ -10,19 +14,38 b' from __future__ import absolute_import'
10 import hashlib
14 import hashlib
11 import struct
15 import struct
12
16
13 from mercurial.node import (
14 nullid,
15 nullrev,
16 )
17 from mercurial import (
17 from mercurial import (
18 extensions,
18 extensions,
19 requirements,
20 revlog,
19 revlog,
21 )
20 )
22
21
23 from mercurial.upgrade_utils import engine as upgrade_engine
22 from mercurial.revlogutils import sidedata as sidedatamod
23
24
25 def compute_sidedata_1(repo, revlog, rev, sidedata, text=None):
26 sidedata = sidedata.copy()
27 if text is None:
28 text = revlog.revision(rev)
29 sidedata[sidedatamod.SD_TEST1] = struct.pack('>I', len(text))
30 return sidedata
31
24
32
25 from mercurial.revlogutils import sidedata
33 def compute_sidedata_2(repo, revlog, rev, sidedata, text=None):
34 sidedata = sidedata.copy()
35 if text is None:
36 text = revlog.revision(rev)
37 sha256 = hashlib.sha256(text).digest()
38 sidedata[sidedatamod.SD_TEST2] = struct.pack('>32s', sha256)
39 return sidedata
40
41
42 def compute_sidedata_3(repo, revlog, rev, sidedata, text=None):
43 sidedata = sidedata.copy()
44 if text is None:
45 text = revlog.revision(rev)
46 sha384 = hashlib.sha384(text).digest()
47 sidedata[sidedatamod.SD_TEST3] = struct.pack('>48s', sha384)
48 return sidedata
26
49
27
50
28 def wrapaddrevision(
51 def wrapaddrevision(
@@ -31,58 +54,35 b' def wrapaddrevision('
31 if kwargs.get('sidedata') is None:
54 if kwargs.get('sidedata') is None:
32 kwargs['sidedata'] = {}
55 kwargs['sidedata'] = {}
33 sd = kwargs['sidedata']
56 sd = kwargs['sidedata']
34 ## let's store some arbitrary data just for testing
57 sd = compute_sidedata_1(None, self, None, sd, text=text)
35 # text length
58 kwargs['sidedata'] = compute_sidedata_2(None, self, None, sd, text=text)
36 sd[sidedata.SD_TEST1] = struct.pack('>I', len(text))
37 # and sha2 hashes
38 sha256 = hashlib.sha256(text).digest()
39 sd[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
40 return orig(self, text, transaction, link, p1, p2, *args, **kwargs)
59 return orig(self, text, transaction, link, p1, p2, *args, **kwargs)
41
60
42
61
43 def wrap_revisiondata(orig, self, nodeorrev, *args, **kwargs):
44 text, sd = orig(self, nodeorrev, *args, **kwargs)
45 if getattr(self, 'sidedatanocheck', False):
46 return text, sd
47 if self.version & 0xFFFF != 2:
48 return text, sd
49 if nodeorrev != nullrev and nodeorrev != nullid:
50 if len(text) != struct.unpack('>I', sd[sidedata.SD_TEST1])[0]:
51 raise RuntimeError('text size mismatch')
52 expected = sd[sidedata.SD_TEST2]
53 got = hashlib.sha256(text).digest()
54 if got != expected:
55 raise RuntimeError('sha256 mismatch')
56 return text, sd
57
58
59 def wrapgetsidedatacompanion(orig, srcrepo, dstrepo):
60 sidedatacompanion = orig(srcrepo, dstrepo)
61 addedreqs = dstrepo.requirements - srcrepo.requirements
62 if requirements.SIDEDATA_REQUIREMENT in addedreqs:
63 assert sidedatacompanion is None # deal with composition later
64
65 def sidedatacompanion(revlog, rev):
66 update = {}
67 revlog.sidedatanocheck = True
68 try:
69 text = revlog.revision(rev)
70 finally:
71 del revlog.sidedatanocheck
72 ## let's store some arbitrary data just for testing
73 # text length
74 update[sidedata.SD_TEST1] = struct.pack('>I', len(text))
75 # and sha2 hashes
76 sha256 = hashlib.sha256(text).digest()
77 update[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
78 return False, (), update, 0, 0
79
80 return sidedatacompanion
81
82
83 def extsetup(ui):
62 def extsetup(ui):
84 extensions.wrapfunction(revlog.revlog, 'addrevision', wrapaddrevision)
63 extensions.wrapfunction(revlog.revlog, 'addrevision', wrapaddrevision)
85 extensions.wrapfunction(revlog.revlog, '_revisiondata', wrap_revisiondata)
64
86 extensions.wrapfunction(
65
87 upgrade_engine, 'getsidedatacompanion', wrapgetsidedatacompanion
66 def reposetup(ui, repo):
67 # Sidedata keys happen to be the same as the categories, easier for testing.
68 for kind in (b'changelog', b'manifest', b'filelog'):
69 repo.register_sidedata_computer(
70 kind,
71 sidedatamod.SD_TEST1,
72 (sidedatamod.SD_TEST1,),
73 compute_sidedata_1,
88 )
74 )
75 repo.register_sidedata_computer(
76 kind,
77 sidedatamod.SD_TEST2,
78 (sidedatamod.SD_TEST2,),
79 compute_sidedata_2,
80 )
81 repo.register_sidedata_computer(
82 kind,
83 sidedatamod.SD_TEST3,
84 (sidedatamod.SD_TEST3,),
85 compute_sidedata_3,
86 )
87 repo.register_wanted_sidedata(sidedatamod.SD_TEST1)
88 repo.register_wanted_sidedata(sidedatamod.SD_TEST2)
@@ -1,88 +1,19 b''
1 # ext-sidedata.py - small extension to test the sidedata logic
1 # coding: utf8
2 # ext-sidedata-4.py - small extension to test (differently still) the sidedata
3 # logic
2 #
4 #
3 # Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net)
5 # Simulates a server for a complex sidedata exchange.
6 #
7 # Copyright 2021 Raphaël Gomès <rgomes@octobus.net>
4 #
8 #
5 # This software may be used and distributed according to the terms of the
9 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
10 # GNU General Public License version 2 or any later version.
7
11
8 from __future__ import absolute_import
12 from __future__ import absolute_import
9
13
10 import hashlib
11 import struct
12
13 from mercurial.node import (
14 nullid,
15 nullrev,
16 )
17 from mercurial import (
18 extensions,
19 requirements,
20 revlog,
21 )
22
23 from mercurial.upgrade_utils import engine as upgrade_engine
24
25 from mercurial.revlogutils import sidedata
14 from mercurial.revlogutils import sidedata
26
15
27
16
28 def wrapaddrevision(
17 def reposetup(ui, repo):
29 orig, self, text, transaction, link, p1, p2, *args, **kwargs
18 repo.register_wanted_sidedata(sidedata.SD_TEST2)
30 ):
19 repo.register_wanted_sidedata(sidedata.SD_TEST3)
31 if kwargs.get('sidedata') is None:
32 kwargs['sidedata'] = {}
33 sd = kwargs['sidedata']
34 ## let's store some arbitrary data just for testing
35 # text length
36 sd[sidedata.SD_TEST1] = struct.pack('>I', len(text))
37 # and sha2 hashes
38 sha256 = hashlib.sha256(text).digest()
39 sd[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
40 return orig(self, text, transaction, link, p1, p2, *args, **kwargs)
41
42
43 def wrap_revisiondata(orig, self, nodeorrev, *args, **kwargs):
44 text, sd = orig(self, nodeorrev, *args, **kwargs)
45 if getattr(self, 'sidedatanocheck', False):
46 return text, sd
47 if self.version & 0xFFFF != 2:
48 return text, sd
49 if nodeorrev != nullrev and nodeorrev != nullid:
50 if len(text) != struct.unpack('>I', sd[sidedata.SD_TEST1])[0]:
51 raise RuntimeError('text size mismatch')
52 expected = sd[sidedata.SD_TEST2]
53 got = hashlib.sha256(text).digest()
54 if got != expected:
55 raise RuntimeError('sha256 mismatch')
56 return text, sd
57
58
59 def wrapgetsidedatacompanion(orig, srcrepo, dstrepo):
60 sidedatacompanion = orig(srcrepo, dstrepo)
61 addedreqs = dstrepo.requirements - srcrepo.requirements
62 if requirements.SIDEDATA_REQUIREMENT in addedreqs:
63 assert sidedatacompanion is None # deal with composition later
64
65 def sidedatacompanion(revlog, rev):
66 update = {}
67 revlog.sidedatanocheck = True
68 try:
69 text = revlog.revision(rev)
70 finally:
71 del revlog.sidedatanocheck
72 ## let's store some arbitrary data just for testing
73 # text length
74 update[sidedata.SD_TEST1] = struct.pack('>I', len(text))
75 # and sha2 hashes
76 sha256 = hashlib.sha256(text).digest()
77 update[sidedata.SD_TEST2] = struct.pack('>32s', sha256)
78 return False, (), update, 0, 0
79
80 return sidedatacompanion
81
82
83 def extsetup(ui):
84 extensions.wrapfunction(revlog.revlog, 'addrevision', wrapaddrevision)
85 extensions.wrapfunction(revlog.revlog, '_revisiondata', wrap_revisiondata)
86 extensions.wrapfunction(
87 upgrade_engine, 'getsidedatacompanion', wrapgetsidedatacompanion
88 )
@@ -1,6 +1,6 b''
1 # ext-sidedata.py - small extension to test the sidedata logic
1 # ext-sidedata.py - small extension to test the sidedata logic
2 #
2 #
3 # Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net)
3 # Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net>
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.
@@ -47,11 +47,12 b' def wrap_revisiondata(orig, self, nodeor'
47 if self.version & 0xFFFF != 2:
47 if self.version & 0xFFFF != 2:
48 return text, sd
48 return text, sd
49 if nodeorrev != nullrev and nodeorrev != nullid:
49 if nodeorrev != nullrev and nodeorrev != nullid:
50 if len(text) != struct.unpack('>I', sd[sidedata.SD_TEST1])[0]:
50 cat1 = sd.get(sidedata.SD_TEST1)
51 if cat1 is not None and len(text) != struct.unpack('>I', cat1)[0]:
51 raise RuntimeError('text size mismatch')
52 raise RuntimeError('text size mismatch')
52 expected = sd[sidedata.SD_TEST2]
53 expected = sd.get(sidedata.SD_TEST2)
53 got = hashlib.sha256(text).digest()
54 got = hashlib.sha256(text).digest()
54 if got != expected:
55 if expected is not None and got != expected:
55 raise RuntimeError('sha256 mismatch')
56 raise RuntimeError('sha256 mismatch')
56 return text, sd
57 return text, sd
57
58
@@ -86,3 +87,10 b' def extsetup(ui):'
86 extensions.wrapfunction(
87 extensions.wrapfunction(
87 upgrade_engine, 'getsidedatacompanion', wrapgetsidedatacompanion
88 upgrade_engine, 'getsidedatacompanion', wrapgetsidedatacompanion
88 )
89 )
90
91
92 def reposetup(ui, repo):
93 # We don't register sidedata computers because we don't care within these
94 # tests
95 repo.register_wanted_sidedata(sidedata.SD_TEST1)
96 repo.register_wanted_sidedata(sidedata.SD_TEST2)
General Comments 0
You need to be logged in to leave comments. Login now