Show More
@@ -395,7 +395,6 b' class changelog(revlog.revlog):' | |||
|
395 | 395 | ``concurrencychecker`` will be passed to the revlog init function, see |
|
396 | 396 | the documentation there. |
|
397 | 397 | """ |
|
398 | ||
|
399 | 398 | revlog.revlog.__init__( |
|
400 | 399 | self, |
|
401 | 400 | opener, |
@@ -484,6 +483,8 b' class changelog(revlog.revlog):' | |||
|
484 | 483 | def _writepending(self, tr): |
|
485 | 484 | """create a file containing the unfinalized state for |
|
486 | 485 | pretxnchangegroup""" |
|
486 | if self._docket: | |
|
487 | return self._docket.write(tr, pending=True) | |
|
487 | 488 | if self._delaybuf: |
|
488 | 489 | # make a temporary copy of the index |
|
489 | 490 | fp1 = self._realopener(self._indexfile) |
@@ -1150,7 +1150,6 b' coreconfigitem(' | |||
|
1150 | 1150 | ) |
|
1151 | 1151 | # "out of experimental" todo list. |
|
1152 | 1152 | # |
|
1153 | # * expose transaction content hooks during pre-commit validation | |
|
1154 | 1153 | # * include management of a persistent nodemap in the main docket |
|
1155 | 1154 | # * enforce a "no-truncate" policy for mmap safety |
|
1156 | 1155 | # - for censoring operation |
@@ -529,7 +529,9 b' class revlog(object):' | |||
|
529 | 529 | if self._initempty: |
|
530 | 530 | self._docket = docketutil.default_docket(self, header) |
|
531 | 531 | else: |
|
532 |
self._docket = docketutil.parse_docket( |
|
|
532 | self._docket = docketutil.parse_docket( | |
|
533 | self, entry_data, use_pending=self._trypending | |
|
534 | ) | |
|
533 | 535 | self._indexfile = self._docket.index_filepath() |
|
534 | 536 | index_data = b'' |
|
535 | 537 | index_size = self._docket.index_end |
@@ -19,6 +19,10 b' from __future__ import absolute_import' | |||
|
19 | 19 | |
|
20 | 20 | import struct |
|
21 | 21 | |
|
22 | from .. import ( | |
|
23 | error, | |
|
24 | ) | |
|
25 | ||
|
22 | 26 | from . import ( |
|
23 | 27 | constants, |
|
24 | 28 | ) |
@@ -29,19 +33,35 b' from . import (' | |||
|
29 | 33 | # | This is mandatory as docket must be compatible with the previous |
|
30 | 34 | # | revlog index header. |
|
31 | 35 | # * 8 bytes: size of index data |
|
32 | S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'L') | |
|
36 | # * 8 bytes: pending size of index data | |
|
37 | S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'LL') | |
|
33 | 38 | |
|
34 | 39 | |
|
35 | 40 | class RevlogDocket(object): |
|
36 | 41 | """metadata associated with revlog""" |
|
37 | 42 | |
|
38 | def __init__(self, revlog, version_header=None, index_end=0): | |
|
43 | def __init__( | |
|
44 | self, | |
|
45 | revlog, | |
|
46 | use_pending=False, | |
|
47 | version_header=None, | |
|
48 | index_end=0, | |
|
49 | pending_index_end=0, | |
|
50 | ): | |
|
39 | 51 | self._version_header = version_header |
|
52 | self._read_only = bool(use_pending) | |
|
40 | 53 | self._dirty = False |
|
41 | 54 | self._radix = revlog.radix |
|
42 | 55 | self._path = revlog._docket_file |
|
43 | 56 | self._opener = revlog.opener |
|
44 | self._index_end = index_end | |
|
57 | # this assert should be True as long as we have a single index filename | |
|
58 | assert index_end <= pending_index_end | |
|
59 | self._initial_index_end = index_end | |
|
60 | self._pending_index_end = pending_index_end | |
|
61 | if use_pending: | |
|
62 | self._index_end = self._pending_index_end | |
|
63 | else: | |
|
64 | self._index_end = self._initial_index_end | |
|
45 | 65 | |
|
46 | 66 | def index_filepath(self): |
|
47 | 67 | """file path to the current index file associated to this docket""" |
@@ -58,22 +78,38 b' class RevlogDocket(object):' | |||
|
58 | 78 | self._index_end = new_size |
|
59 | 79 | self._dirty = True |
|
60 | 80 | |
|
61 | def write(self, transaction, stripping=False): | |
|
81 | def write(self, transaction, pending=False, stripping=False): | |
|
62 | 82 | """write the modification of disk if any |
|
63 | 83 | |
|
64 | 84 | This make the new content visible to all process""" |
|
65 | if self._dirty: | |
|
85 | if not self._dirty: | |
|
86 | return False | |
|
87 | else: | |
|
88 | if self._read_only: | |
|
89 | msg = b'writing read-only docket: %s' | |
|
90 | msg %= self._path | |
|
91 | raise error.ProgrammingError(msg) | |
|
66 | 92 | if not stripping: |
|
67 | 93 | # XXX we could, leverage the docket while stripping. However it |
|
68 | 94 | # is not powerfull enough at the time of this comment |
|
69 | 95 | transaction.addbackup(self._path, location=b'store') |
|
70 | 96 | with self._opener(self._path, mode=b'w', atomictemp=True) as f: |
|
71 | f.write(self._serialize()) | |
|
72 | self._dirty = False | |
|
97 | f.write(self._serialize(pending=pending)) | |
|
98 | # if pending we still need to the write final data eventually | |
|
99 | self._dirty = pending | |
|
100 | return True | |
|
73 | 101 | |
|
74 | def _serialize(self): | |
|
102 | def _serialize(self, pending=False): | |
|
103 | if pending: | |
|
104 | official_index_end = self._initial_index_end | |
|
105 | else: | |
|
106 | official_index_end = self._index_end | |
|
107 | ||
|
108 | # this assert should be True as long as we have a single index filename | |
|
109 | assert official_index_end <= self._index_end | |
|
75 | 110 | data = ( |
|
76 | 111 | self._version_header, |
|
112 | official_index_end, | |
|
77 | 113 | self._index_end, |
|
78 | 114 | ) |
|
79 | 115 | return S_HEADER.pack(*data) |
@@ -88,13 +124,15 b' def default_docket(revlog, version_heade' | |||
|
88 | 124 | return docket |
|
89 | 125 | |
|
90 | 126 | |
|
91 | def parse_docket(revlog, data): | |
|
127 | def parse_docket(revlog, data, use_pending=False): | |
|
92 | 128 | """given some docket data return a docket object for the given revlog""" |
|
93 | 129 | header = S_HEADER.unpack(data[: S_HEADER.size]) |
|
94 | version_header, index_size = header | |
|
130 | version_header, index_size, pending_index_size = header | |
|
95 | 131 | docket = RevlogDocket( |
|
96 | 132 | revlog, |
|
133 | use_pending=use_pending, | |
|
97 | 134 | version_header=version_header, |
|
98 | 135 | index_end=index_size, |
|
136 | pending_index_end=pending_index_size, | |
|
99 | 137 | ) |
|
100 | 138 | return docket |
@@ -46,13 +46,13 b' synchronisation+output script:' | |||
|
46 | 46 | $ cat << EOF > script/external.sh |
|
47 | 47 | > #!/bin/sh |
|
48 | 48 | > $RUNTESTDIR/testlib/wait-on-file 5 $HG_TEST_FILE_EXT_UNLOCK $HG_TEST_FILE_EXT_WAITING |
|
49 |
> hg log --rev 'tip' -T 'external: {rev} {desc}\n' > $TESTTMP/output/external.out |
|
|
49 | > hg log --rev 'tip' -T 'external: {rev} {desc}\n' > $TESTTMP/output/external.out | |
|
50 | 50 | > touch $HG_TEST_FILE_EXT_DONE |
|
51 | 51 | > EOF |
|
52 | 52 | $ chmod +x script/external.sh |
|
53 | 53 | $ cat << EOF > script/internal.sh |
|
54 | 54 | > #!/bin/sh |
|
55 |
> hg log --rev 'tip' -T 'internal: {rev} {desc}\n' > $TESTTMP/output/internal.out |
|
|
55 | > hg log --rev 'tip' -T 'internal: {rev} {desc}\n' > $TESTTMP/output/internal.out | |
|
56 | 56 | > $RUNTESTDIR/testlib/wait-on-file 5 $HG_TEST_FILE_EXT_DONE $HG_TEST_FILE_EXT_UNLOCK |
|
57 | 57 | > EOF |
|
58 | 58 | $ chmod +x script/internal.sh |
@@ -124,8 +124,7 b' the repository should still be inline (f' | |||
|
124 | 124 | $ make_one_commit first |
|
125 | 125 | pre-commit: -1 |
|
126 | 126 | external: -1 |
|
127 |
internal: 0 first |
|
|
128 | internal: -1 (revlogv2 known-bad-output !) | |
|
127 | internal: 0 first | |
|
129 | 128 | post-tr: 0 first |
|
130 | 129 | |
|
131 | 130 | #if revlogv1 |
@@ -150,8 +149,7 b' the repository should still be inline (f' | |||
|
150 | 149 | $ make_one_commit second |
|
151 | 150 | pre-commit: 0 first |
|
152 | 151 | external: 0 first |
|
153 |
internal: 1 second |
|
|
154 | internal: 0 first (revlogv2 known-bad-output !) | |
|
152 | internal: 1 second | |
|
155 | 153 | post-tr: 1 second |
|
156 | 154 | |
|
157 | 155 | #if revlogv1 |
@@ -177,8 +175,7 b' the repository should still be inline (f' | |||
|
177 | 175 | pre-commit: 1 second |
|
178 | 176 | warning: repository is unrelated |
|
179 | 177 | external: 1 second |
|
180 |
internal: 5 r3 |
|
|
181 | internal: 1 second (revlogv2 known-bad-output !) | |
|
178 | internal: 5 r3 | |
|
182 | 179 | post-tr: 5 r3 |
|
183 | 180 | |
|
184 | 181 | #if revlogv1 |
@@ -203,8 +200,7 b' the repository should no longer be inlin' | |||
|
203 | 200 | $ make_one_pull 400 |
|
204 | 201 | pre-commit: 5 r3 |
|
205 | 202 | external: 5 r3 |
|
206 |
internal: 402 r400 |
|
|
207 | internal: 5 r3 (revlogv2 known-bad-output !) | |
|
203 | internal: 402 r400 | |
|
208 | 204 | post-tr: 402 r400 |
|
209 | 205 | |
|
210 | 206 | #if revlogv1 |
@@ -229,8 +225,7 b' the repository should no longer be inlin' | |||
|
229 | 225 | $ make_one_commit third |
|
230 | 226 | pre-commit: 402 r400 |
|
231 | 227 | external: 402 r400 |
|
232 |
internal: 403 third |
|
|
233 | internal: 402 r400 (revlogv2 known-bad-output !) | |
|
228 | internal: 403 third | |
|
234 | 229 | post-tr: 403 third |
|
235 | 230 | |
|
236 | 231 | #if revlogv1 |
@@ -256,8 +251,7 b' the repository should no longer be inlin' | |||
|
256 | 251 | $ make_one_pull tip |
|
257 | 252 | pre-commit: 403 third |
|
258 | 253 | external: 403 third |
|
259 |
internal: 503 r500 |
|
|
260 | internal: 403 third (revlogv2 known-bad-output !) | |
|
254 | internal: 503 r500 | |
|
261 | 255 | post-tr: 503 r500 |
|
262 | 256 | |
|
263 | 257 | #if revlogv1 |
General Comments 0
You need to be logged in to leave comments.
Login now