Show More
@@ -331,6 +331,8 b' class remotefilelog(object):' | |||||
331 | delta=delta, |
|
331 | delta=delta, | |
332 | # Sidedata is not supported yet |
|
332 | # Sidedata is not supported yet | |
333 | sidedata=None, |
|
333 | sidedata=None, | |
|
334 | # Protocol flags are not used yet | |||
|
335 | protocol_flags=0, | |||
334 | ) |
|
336 | ) | |
335 |
|
337 | |||
336 | def revdiff(self, node1, node2): |
|
338 | def revdiff(self, node1, node2): |
@@ -289,6 +289,7 b' class sqliterevisiondelta(object):' | |||||
289 | revision = attr.ib() |
|
289 | revision = attr.ib() | |
290 | delta = attr.ib() |
|
290 | delta = attr.ib() | |
291 | sidedata = attr.ib() |
|
291 | sidedata = attr.ib() | |
|
292 | protocol_flags = attr.ib() | |||
292 | linknode = attr.ib(default=None) |
|
293 | linknode = attr.ib(default=None) | |
293 |
|
294 | |||
294 |
|
295 |
@@ -34,10 +34,12 b' from . import (' | |||||
34 | from .interfaces import repository |
|
34 | from .interfaces import repository | |
35 | from .revlogutils import sidedata as sidedatamod |
|
35 | from .revlogutils import sidedata as sidedatamod | |
36 | from .revlogutils import constants as revlog_constants |
|
36 | from .revlogutils import constants as revlog_constants | |
|
37 | from .utils import storageutil | |||
37 |
|
38 | |||
38 | _CHANGEGROUPV1_DELTA_HEADER = struct.Struct(b"20s20s20s20s") |
|
39 | _CHANGEGROUPV1_DELTA_HEADER = struct.Struct(b"20s20s20s20s") | |
39 | _CHANGEGROUPV2_DELTA_HEADER = struct.Struct(b"20s20s20s20s20s") |
|
40 | _CHANGEGROUPV2_DELTA_HEADER = struct.Struct(b"20s20s20s20s20s") | |
40 | _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(b">20s20s20s20s20sH") |
|
41 | _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(b">20s20s20s20s20sH") | |
|
42 | _CHANGEGROUPV4_DELTA_HEADER = struct.Struct(b">B20s20s20s20s20sH") | |||
41 |
|
43 | |||
42 | LFS_REQUIREMENT = b'lfs' |
|
44 | LFS_REQUIREMENT = b'lfs' | |
43 |
|
45 | |||
@@ -194,7 +196,8 b' class cg1unpacker(object):' | |||||
194 | else: |
|
196 | else: | |
195 | deltabase = prevnode |
|
197 | deltabase = prevnode | |
196 | flags = 0 |
|
198 | flags = 0 | |
197 | return node, p1, p2, deltabase, cs, flags |
|
199 | protocol_flags = 0 | |
|
200 | return node, p1, p2, deltabase, cs, flags, protocol_flags | |||
198 |
|
201 | |||
199 | def deltachunk(self, prevnode): |
|
202 | def deltachunk(self, prevnode): | |
200 | l = self._chunklength() |
|
203 | l = self._chunklength() | |
@@ -203,10 +206,9 b' class cg1unpacker(object):' | |||||
203 | headerdata = readexactly(self._stream, self.deltaheadersize) |
|
206 | headerdata = readexactly(self._stream, self.deltaheadersize) | |
204 | header = self.deltaheader.unpack(headerdata) |
|
207 | header = self.deltaheader.unpack(headerdata) | |
205 | delta = readexactly(self._stream, l - self.deltaheadersize) |
|
208 | delta = readexactly(self._stream, l - self.deltaheadersize) | |
206 |
|
|
209 | header = self._deltaheader(header, prevnode) | |
207 | # cg4 forward-compat |
|
210 | node, p1, p2, deltabase, cs, flags, protocol_flags = header | |
208 | sidedata = {} |
|
211 | return node, p1, p2, cs, deltabase, delta, flags, protocol_flags | |
209 | return (node, p1, p2, cs, deltabase, delta, flags, sidedata) |
|
|||
210 |
|
212 | |||
211 | def getchunks(self): |
|
213 | def getchunks(self): | |
212 | """returns all the chunks contains in the bundle |
|
214 | """returns all the chunks contains in the bundle | |
@@ -597,7 +599,8 b' class cg2unpacker(cg1unpacker):' | |||||
597 | def _deltaheader(self, headertuple, prevnode): |
|
599 | def _deltaheader(self, headertuple, prevnode): | |
598 | node, p1, p2, deltabase, cs = headertuple |
|
600 | node, p1, p2, deltabase, cs = headertuple | |
599 | flags = 0 |
|
601 | flags = 0 | |
600 | return node, p1, p2, deltabase, cs, flags |
|
602 | protocol_flags = 0 | |
|
603 | return node, p1, p2, deltabase, cs, flags, protocol_flags | |||
601 |
|
604 | |||
602 |
|
605 | |||
603 | class cg3unpacker(cg2unpacker): |
|
606 | class cg3unpacker(cg2unpacker): | |
@@ -615,7 +618,8 b' class cg3unpacker(cg2unpacker):' | |||||
615 |
|
618 | |||
616 | def _deltaheader(self, headertuple, prevnode): |
|
619 | def _deltaheader(self, headertuple, prevnode): | |
617 | node, p1, p2, deltabase, cs, flags = headertuple |
|
620 | node, p1, p2, deltabase, cs, flags = headertuple | |
618 | return node, p1, p2, deltabase, cs, flags |
|
621 | protocol_flags = 0 | |
|
622 | return node, p1, p2, deltabase, cs, flags, protocol_flags | |||
619 |
|
623 | |||
620 | def _unpackmanifests(self, repo, revmap, trp, prog, addrevisioncb=None): |
|
624 | def _unpackmanifests(self, repo, revmap, trp, prog, addrevisioncb=None): | |
621 | super(cg3unpacker, self)._unpackmanifests( |
|
625 | super(cg3unpacker, self)._unpackmanifests( | |
@@ -638,18 +642,24 b' class cg4unpacker(cg3unpacker):' | |||||
638 | cg4 streams add support for exchanging sidedata. |
|
642 | cg4 streams add support for exchanging sidedata. | |
639 | """ |
|
643 | """ | |
640 |
|
644 | |||
|
645 | deltaheader = _CHANGEGROUPV4_DELTA_HEADER | |||
|
646 | deltaheadersize = deltaheader.size | |||
641 | version = b'04' |
|
647 | version = b'04' | |
642 |
|
648 | |||
|
649 | def _deltaheader(self, headertuple, prevnode): | |||
|
650 | protocol_flags, node, p1, p2, deltabase, cs, flags = headertuple | |||
|
651 | return node, p1, p2, deltabase, cs, flags, protocol_flags | |||
|
652 | ||||
643 | def deltachunk(self, prevnode): |
|
653 | def deltachunk(self, prevnode): | |
644 | res = super(cg4unpacker, self).deltachunk(prevnode) |
|
654 | res = super(cg4unpacker, self).deltachunk(prevnode) | |
645 | if not res: |
|
655 | if not res: | |
646 | return res |
|
656 | return res | |
647 |
|
657 | |||
648 |
(node, p1, p2, cs, deltabase, delta, flags, _s |
|
658 | (node, p1, p2, cs, deltabase, delta, flags, protocol_flags) = res | |
649 |
|
659 | |||
650 | sidedata_raw = getchunk(self._stream) |
|
|||
651 | sidedata = {} |
|
660 | sidedata = {} | |
652 | if len(sidedata_raw) > 0: |
|
661 | if protocol_flags & storageutil.CG_FLAG_SIDEDATA: | |
|
662 | sidedata_raw = getchunk(self._stream) | |||
653 | sidedata = sidedatamod.deserialize_sidedata(sidedata_raw) |
|
663 | sidedata = sidedatamod.deserialize_sidedata(sidedata_raw) | |
654 |
|
664 | |||
655 | return node, p1, p2, cs, deltabase, delta, flags, sidedata |
|
665 | return node, p1, p2, cs, deltabase, delta, flags, sidedata | |
@@ -695,10 +705,10 b' def _revisiondeltatochunks(repo, delta, ' | |||||
695 | yield prefix |
|
705 | yield prefix | |
696 | yield data |
|
706 | yield data | |
697 |
|
707 | |||
698 | sidedata = delta.sidedata |
|
708 | if delta.protocol_flags & storageutil.CG_FLAG_SIDEDATA: | |
699 | if sidedata is not None: |
|
|||
700 | # Need a separate chunk for sidedata to be able to differentiate |
|
709 | # Need a separate chunk for sidedata to be able to differentiate | |
701 | # "raw delta" length and sidedata length |
|
710 | # "raw delta" length and sidedata length | |
|
711 | sidedata = delta.sidedata | |||
702 | yield chunkheader(len(sidedata)) |
|
712 | yield chunkheader(len(sidedata)) | |
703 | yield sidedata |
|
713 | yield sidedata | |
704 |
|
714 | |||
@@ -1640,11 +1650,18 b' def _makecg4packer(' | |||||
1640 | fullnodes=None, |
|
1650 | fullnodes=None, | |
1641 | remote_sidedata=None, |
|
1651 | remote_sidedata=None, | |
1642 | ): |
|
1652 | ): | |
1643 |
# S |
|
1653 | # Sidedata is in a separate chunk from the delta to differentiate | |
1644 |
# |
|
1654 | # "raw delta" and sidedata. | |
1645 | builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( |
|
1655 | def builddeltaheader(d): | |
1646 | d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags |
|
1656 | return _CHANGEGROUPV4_DELTA_HEADER.pack( | |
1647 | ) |
|
1657 | d.protocol_flags, | |
|
1658 | d.node, | |||
|
1659 | d.p1node, | |||
|
1660 | d.p2node, | |||
|
1661 | d.basenode, | |||
|
1662 | d.linknode, | |||
|
1663 | d.flags, | |||
|
1664 | ) | |||
1648 |
|
1665 | |||
1649 | return cgpacker( |
|
1666 | return cgpacker( | |
1650 | repo, |
|
1667 | repo, | |
@@ -1930,7 +1947,6 b' def get_sidedata_helpers(repo, remote_sd' | |||||
1930 | sd_computers = collections.defaultdict(list) |
|
1947 | sd_computers = collections.defaultdict(list) | |
1931 | # Computers for categories to remove from sidedata |
|
1948 | # Computers for categories to remove from sidedata | |
1932 | sd_removers = collections.defaultdict(list) |
|
1949 | sd_removers = collections.defaultdict(list) | |
1933 |
|
||||
1934 | to_generate = remote_sd_categories - repo._wanted_sidedata |
|
1950 | to_generate = remote_sd_categories - repo._wanted_sidedata | |
1935 | to_remove = repo._wanted_sidedata - remote_sd_categories |
|
1951 | to_remove = repo._wanted_sidedata - remote_sd_categories | |
1936 | if pull: |
|
1952 | if pull: |
@@ -2,12 +2,13 b' Changegroups are representations of repo' | |||||
2 | the changelog data, root/flat manifest data, treemanifest data, and |
|
2 | the changelog data, root/flat manifest data, treemanifest data, and | |
3 | filelogs. |
|
3 | filelogs. | |
4 |
|
4 | |||
5 |
There are |
|
5 | There are 4 versions of changegroups: ``1``, ``2``, ``3`` and ``4``. From a | |
6 | high-level, versions ``1`` and ``2`` are almost exactly the same, with the |
|
6 | high-level, versions ``1`` and ``2`` are almost exactly the same, with the | |
7 | only difference being an additional item in the *delta header*. Version |
|
7 | only difference being an additional item in the *delta header*. Version | |
8 | ``3`` adds support for storage flags in the *delta header* and optionally |
|
8 | ``3`` adds support for storage flags in the *delta header* and optionally | |
9 | exchanging treemanifests (enabled by setting an option on the |
|
9 | exchanging treemanifests (enabled by setting an option on the | |
10 | ``changegroup`` part in the bundle2). |
|
10 | ``changegroup`` part in the bundle2). Version ``4`` adds support for exchanging | |
|
11 | sidedata (additional revision metadata not part of the digest). | |||
11 |
|
12 | |||
12 | Changegroups when not exchanging treemanifests consist of 3 logical |
|
13 | Changegroups when not exchanging treemanifests consist of 3 logical | |
13 | segments:: |
|
14 | segments:: | |
@@ -74,8 +75,8 b' The *delta data* is a series of *delta*s' | |||||
74 | entry (either that the recipient already has, or previously specified in the |
|
75 | entry (either that the recipient already has, or previously specified in the | |
75 | bundle/changegroup). |
|
76 | bundle/changegroup). | |
76 |
|
77 | |||
77 | The *delta header* is different between versions ``1``, ``2``, and |
|
78 | The *delta header* is different between versions ``1``, ``2``, ``3`` and ``4`` | |
78 |
|
|
79 | of the changegroup format. | |
79 |
|
80 | |||
80 | Version 1 (headerlen=80):: |
|
81 | Version 1 (headerlen=80):: | |
81 |
|
82 | |||
@@ -104,6 +105,15 b' Version 3 (headerlen=102)::' | |||||
104 | | | | | | | | |
|
105 | | | | | | | | | |
105 | +------------------------------------------------------------------------------+ |
|
106 | +------------------------------------------------------------------------------+ | |
106 |
|
107 | |||
|
108 | Version 4 (headerlen=103):: | |||
|
109 | ||||
|
110 | +------------------------------------------------------------------------------+----------+ | |||
|
111 | | | | | | | | | | |||
|
112 | | node | p1 node | p2 node | base node | link node | flags | pflags | | |||
|
113 | | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) | | |||
|
114 | | | | | | | | | | |||
|
115 | +------------------------------------------------------------------------------+----------+ | |||
|
116 | ||||
107 | The *delta data* consists of ``chunklen - 4 - headerlen`` bytes, which contain a |
|
117 | The *delta data* consists of ``chunklen - 4 - headerlen`` bytes, which contain a | |
108 | series of *delta*s, densely packed (no separators). These deltas describe a diff |
|
118 | series of *delta*s, densely packed (no separators). These deltas describe a diff | |
109 | from an existing entry (either that the recipient already has, or previously |
|
119 | from an existing entry (either that the recipient already has, or previously | |
@@ -140,12 +150,24 b' 8192' | |||||
140 | Externally stored. The revision fulltext contains ``key:value`` ``\n`` |
|
150 | Externally stored. The revision fulltext contains ``key:value`` ``\n`` | |
141 | delimited metadata defining an object stored elsewhere. Used by the LFS |
|
151 | delimited metadata defining an object stored elsewhere. Used by the LFS | |
142 | extension. |
|
152 | extension. | |
|
153 | 4096 | |||
|
154 | Contains copy information. This revision changes files in a way that could | |||
|
155 | affect copy tracing. This does *not* affect changegroup handling, but is | |||
|
156 | relevant for other parts of Mercurial. | |||
143 |
|
157 | |||
144 | For historical reasons, the integer values are identical to revlog version 1 |
|
158 | For historical reasons, the integer values are identical to revlog version 1 | |
145 | per-revision storage flags and correspond to bits being set in this 2-byte |
|
159 | per-revision storage flags and correspond to bits being set in this 2-byte | |
146 | field. Bits were allocated starting from the most-significant bit, hence the |
|
160 | field. Bits were allocated starting from the most-significant bit, hence the | |
147 | reverse ordering and allocation of these flags. |
|
161 | reverse ordering and allocation of these flags. | |
148 |
|
162 | |||
|
163 | The *pflags* (protocol flags) field holds bitwise flags affecting the protocol | |||
|
164 | itself. They are first in the header since they may affect the handling of the | |||
|
165 | rest of the fields in a future version. They are defined as such: | |||
|
166 | ||||
|
167 | 1 indicates whether to read a chunk of sidedata (of variable length) right | |||
|
168 | after the revision flags. | |||
|
169 | ||||
|
170 | ||||
149 | Changeset Segment |
|
171 | Changeset Segment | |
150 | ================= |
|
172 | ================= | |
151 |
|
173 | |||
@@ -166,9 +188,9 b' the boundary to the next segment (either' | |||||
166 | Treemanifests Segment |
|
188 | Treemanifests Segment | |
167 | --------------------- |
|
189 | --------------------- | |
168 |
|
190 | |||
169 |
The *treemanifests segment* only exists in changegroup version ``3`` |
|
191 | The *treemanifests segment* only exists in changegroup version ``3`` and ``4``, | |
170 | only if the 'treemanifest' param is part of the bundle2 changegroup part |
|
192 | and only if the 'treemanifest' param is part of the bundle2 changegroup part | |
171 | (it is not possible to use changegroup version 3 outside of bundle2). |
|
193 | (it is not possible to use changegroup version 3 or 4 outside of bundle2). | |
172 | Aside from the filenames in the *treemanifests segment* containing a |
|
194 | Aside from the filenames in the *treemanifests segment* containing a | |
173 | trailing ``/`` character, it behaves identically to the *filelogs segment* |
|
195 | trailing ``/`` character, it behaves identically to the *filelogs segment* | |
174 | (see below). The final sub-segment is followed by an *empty chunk* (logically, |
|
196 | (see below). The final sub-segment is followed by an *empty chunk* (logically, |
@@ -27,14 +27,12 b" REPO_FEATURE_SHALLOW_FILE_STORAGE = b'sh" | |||||
27 | REVISION_FLAG_CENSORED = 1 << 15 |
|
27 | REVISION_FLAG_CENSORED = 1 << 15 | |
28 | REVISION_FLAG_ELLIPSIS = 1 << 14 |
|
28 | REVISION_FLAG_ELLIPSIS = 1 << 14 | |
29 | REVISION_FLAG_EXTSTORED = 1 << 13 |
|
29 | REVISION_FLAG_EXTSTORED = 1 << 13 | |
30 |
REVISION_FLAG_ |
|
30 | REVISION_FLAG_HASCOPIESINFO = 1 << 12 | |
31 | REVISION_FLAG_HASCOPIESINFO = 1 << 11 |
|
|||
32 |
|
31 | |||
33 | REVISION_FLAGS_KNOWN = ( |
|
32 | REVISION_FLAGS_KNOWN = ( | |
34 | REVISION_FLAG_CENSORED |
|
33 | REVISION_FLAG_CENSORED | |
35 | | REVISION_FLAG_ELLIPSIS |
|
34 | | REVISION_FLAG_ELLIPSIS | |
36 | | REVISION_FLAG_EXTSTORED |
|
35 | | REVISION_FLAG_EXTSTORED | |
37 | | REVISION_FLAG_SIDEDATA |
|
|||
38 | | REVISION_FLAG_HASCOPIESINFO |
|
36 | | REVISION_FLAG_HASCOPIESINFO | |
39 | ) |
|
37 | ) | |
40 |
|
38 | |||
@@ -457,6 +455,13 b' class irevisiondelta(interfaceutil.Inter' | |||||
457 | """Raw sidedata bytes for the given revision.""" |
|
455 | """Raw sidedata bytes for the given revision.""" | |
458 | ) |
|
456 | ) | |
459 |
|
457 | |||
|
458 | protocol_flags = interfaceutil.Attribute( | |||
|
459 | """Single byte of integer flags that can influence the protocol. | |||
|
460 | ||||
|
461 | This is a bitwise composition of the ``storageutil.CG_FLAG*`` constants. | |||
|
462 | """ | |||
|
463 | ) | |||
|
464 | ||||
460 |
|
465 | |||
461 | class ifilerevisionssequence(interfaceutil.Interface): |
|
466 | class ifilerevisionssequence(interfaceutil.Interface): | |
462 | """Contains index data for all revisions of a file. |
|
467 | """Contains index data for all revisions of a file. |
@@ -55,7 +55,6 b' from .revlogutils.flagutil import (' | |||||
55 | REVIDX_HASCOPIESINFO, |
|
55 | REVIDX_HASCOPIESINFO, | |
56 | REVIDX_ISCENSORED, |
|
56 | REVIDX_ISCENSORED, | |
57 | REVIDX_RAWTEXT_CHANGING_FLAGS, |
|
57 | REVIDX_RAWTEXT_CHANGING_FLAGS, | |
58 | REVIDX_SIDEDATA, |
|
|||
59 | ) |
|
58 | ) | |
60 | from .thirdparty import attr |
|
59 | from .thirdparty import attr | |
61 | from . import ( |
|
60 | from . import ( | |
@@ -98,7 +97,6 b' REVLOGV1_FLAGS' | |||||
98 | REVLOGV2_FLAGS |
|
97 | REVLOGV2_FLAGS | |
99 | REVIDX_ISCENSORED |
|
98 | REVIDX_ISCENSORED | |
100 | REVIDX_ELLIPSIS |
|
99 | REVIDX_ELLIPSIS | |
101 | REVIDX_SIDEDATA |
|
|||
102 | REVIDX_HASCOPIESINFO |
|
100 | REVIDX_HASCOPIESINFO | |
103 | REVIDX_EXTSTORED |
|
101 | REVIDX_EXTSTORED | |
104 | REVIDX_DEFAULT_FLAGS |
|
102 | REVIDX_DEFAULT_FLAGS | |
@@ -196,6 +194,7 b' class revlogrevisiondelta(object):' | |||||
196 | revision = attr.ib() |
|
194 | revision = attr.ib() | |
197 | delta = attr.ib() |
|
195 | delta = attr.ib() | |
198 | sidedata = attr.ib() |
|
196 | sidedata = attr.ib() | |
|
197 | protocol_flags = attr.ib() | |||
199 | linknode = attr.ib(default=None) |
|
198 | linknode = attr.ib(default=None) | |
200 |
|
199 | |||
201 |
|
200 |
@@ -99,8 +99,6 b' REVIDX_ISCENSORED = repository.REVISION_' | |||||
99 | REVIDX_ELLIPSIS = repository.REVISION_FLAG_ELLIPSIS |
|
99 | REVIDX_ELLIPSIS = repository.REVISION_FLAG_ELLIPSIS | |
100 | # revision data is stored externally |
|
100 | # revision data is stored externally | |
101 | REVIDX_EXTSTORED = repository.REVISION_FLAG_EXTSTORED |
|
101 | REVIDX_EXTSTORED = repository.REVISION_FLAG_EXTSTORED | |
102 | # revision data contains extra metadata not part of the official digest |
|
|||
103 | REVIDX_SIDEDATA = repository.REVISION_FLAG_SIDEDATA |
|
|||
104 | # revision changes files in a way that could affect copy tracing. |
|
102 | # revision changes files in a way that could affect copy tracing. | |
105 | REVIDX_HASCOPIESINFO = repository.REVISION_FLAG_HASCOPIESINFO |
|
103 | REVIDX_HASCOPIESINFO = repository.REVISION_FLAG_HASCOPIESINFO | |
106 | REVIDX_DEFAULT_FLAGS = 0 |
|
104 | REVIDX_DEFAULT_FLAGS = 0 | |
@@ -109,13 +107,10 b' REVIDX_FLAGS_ORDER = [' | |||||
109 | REVIDX_ISCENSORED, |
|
107 | REVIDX_ISCENSORED, | |
110 | REVIDX_ELLIPSIS, |
|
108 | REVIDX_ELLIPSIS, | |
111 | REVIDX_EXTSTORED, |
|
109 | REVIDX_EXTSTORED, | |
112 | REVIDX_SIDEDATA, |
|
|||
113 | REVIDX_HASCOPIESINFO, |
|
110 | REVIDX_HASCOPIESINFO, | |
114 | ] |
|
111 | ] | |
115 |
|
112 | |||
116 | # bitmark for flags that could cause rawdata content change |
|
113 | # bitmark for flags that could cause rawdata content change | |
117 |
REVIDX_RAWTEXT_CHANGING_FLAGS = |
|
114 | REVIDX_RAWTEXT_CHANGING_FLAGS = REVIDX_ISCENSORED | REVIDX_EXTSTORED | |
118 | REVIDX_ISCENSORED | REVIDX_EXTSTORED | REVIDX_SIDEDATA |
|
|||
119 | ) |
|
|||
120 |
|
115 | |||
121 | SPARSE_REVLOG_MAX_CHAIN_LENGTH = 1000 |
|
116 | SPARSE_REVLOG_MAX_CHAIN_LENGTH = 1000 |
@@ -18,7 +18,6 b' from .constants import (' | |||||
18 | REVIDX_HASCOPIESINFO, |
|
18 | REVIDX_HASCOPIESINFO, | |
19 | REVIDX_ISCENSORED, |
|
19 | REVIDX_ISCENSORED, | |
20 | REVIDX_RAWTEXT_CHANGING_FLAGS, |
|
20 | REVIDX_RAWTEXT_CHANGING_FLAGS, | |
21 | REVIDX_SIDEDATA, |
|
|||
22 | ) |
|
21 | ) | |
23 |
|
22 | |||
24 | from .. import error, util |
|
23 | from .. import error, util | |
@@ -28,7 +27,6 b' from .. import error, util' | |||||
28 | REVIDX_ISCENSORED |
|
27 | REVIDX_ISCENSORED | |
29 | REVIDX_ELLIPSIS |
|
28 | REVIDX_ELLIPSIS | |
30 | REVIDX_EXTSTORED |
|
29 | REVIDX_EXTSTORED | |
31 | REVIDX_SIDEDATA |
|
|||
32 | REVIDX_HASCOPIESINFO, |
|
30 | REVIDX_HASCOPIESINFO, | |
33 | REVIDX_DEFAULT_FLAGS |
|
31 | REVIDX_DEFAULT_FLAGS | |
34 | REVIDX_FLAGS_ORDER |
|
32 | REVIDX_FLAGS_ORDER |
@@ -28,6 +28,10 b' from ..utils import hashutil' | |||||
28 |
|
28 | |||
29 | _nullhash = hashutil.sha1(sha1nodeconstants.nullid) |
|
29 | _nullhash = hashutil.sha1(sha1nodeconstants.nullid) | |
30 |
|
30 | |||
|
31 | # revision data contains extra metadata not part of the official digest | |||
|
32 | # Only used in changegroup >= v4. | |||
|
33 | CG_FLAG_SIDEDATA = 1 | |||
|
34 | ||||
31 |
|
35 | |||
32 | def hashrevisionsha1(text, p1, p2): |
|
36 | def hashrevisionsha1(text, p1, p2): | |
33 | """Compute the SHA-1 for revision data and its parents. |
|
37 | """Compute the SHA-1 for revision data and its parents. | |
@@ -486,7 +490,7 b' def emitrevisions(' | |||||
486 |
|
490 | |||
487 | available.add(rev) |
|
491 | available.add(rev) | |
488 |
|
492 | |||
489 | sidedata = None |
|
493 | serialized_sidedata = None | |
490 | if sidedata_helpers: |
|
494 | if sidedata_helpers: | |
491 | sidedata = store.sidedata(rev) |
|
495 | sidedata = store.sidedata(rev) | |
492 | sidedata = run_sidedata_helpers( |
|
496 | sidedata = run_sidedata_helpers( | |
@@ -495,18 +499,26 b' def emitrevisions(' | |||||
495 | sidedata=sidedata, |
|
499 | sidedata=sidedata, | |
496 | rev=rev, |
|
500 | rev=rev, | |
497 | ) |
|
501 | ) | |
498 | sidedata = sidedatamod.serialize_sidedata(sidedata) |
|
502 | if sidedata: | |
|
503 | serialized_sidedata = sidedatamod.serialize_sidedata(sidedata) | |||
|
504 | ||||
|
505 | flags = flagsfn(rev) if flagsfn else 0 | |||
|
506 | protocol_flags = 0 | |||
|
507 | if serialized_sidedata: | |||
|
508 | # Advertise that sidedata exists to the other side | |||
|
509 | protocol_flags |= CG_FLAG_SIDEDATA | |||
499 |
|
510 | |||
500 | yield resultcls( |
|
511 | yield resultcls( | |
501 | node=node, |
|
512 | node=node, | |
502 | p1node=fnode(p1rev), |
|
513 | p1node=fnode(p1rev), | |
503 | p2node=fnode(p2rev), |
|
514 | p2node=fnode(p2rev), | |
504 | basenode=fnode(baserev), |
|
515 | basenode=fnode(baserev), | |
505 |
flags=flags |
|
516 | flags=flags, | |
506 | baserevisionsize=baserevisionsize, |
|
517 | baserevisionsize=baserevisionsize, | |
507 | revision=revision, |
|
518 | revision=revision, | |
508 | delta=delta, |
|
519 | delta=delta, | |
509 | sidedata=sidedata, |
|
520 | sidedata=serialized_sidedata, | |
|
521 | protocol_flags=protocol_flags, | |||
510 | ) |
|
522 | ) | |
511 |
|
523 | |||
512 | prevrev = rev |
|
524 | prevrev = rev |
@@ -282,6 +282,7 b' def main():' | |||||
282 | revision=b'', |
|
282 | revision=b'', | |
283 | sidedata=b'', |
|
283 | sidedata=b'', | |
284 | delta=None, |
|
284 | delta=None, | |
|
285 | protocol_flags=b'', | |||
285 | ) |
|
286 | ) | |
286 | checkzobject(rd) |
|
287 | checkzobject(rd) | |
287 |
|
288 |
@@ -1136,12 +1136,13 b' sub-topics can be accessed' | |||||
1136 | the changelog data, root/flat manifest data, treemanifest data, and |
|
1136 | the changelog data, root/flat manifest data, treemanifest data, and | |
1137 | filelogs. |
|
1137 | filelogs. | |
1138 |
|
1138 | |||
1139 |
There are |
|
1139 | There are 4 versions of changegroups: "1", "2", "3" and "4". From a high- | |
1140 | level, versions "1" and "2" are almost exactly the same, with the only |
|
1140 | level, versions "1" and "2" are almost exactly the same, with the only | |
1141 | difference being an additional item in the *delta header*. Version "3" |
|
1141 | difference being an additional item in the *delta header*. Version "3" | |
1142 | adds support for storage flags in the *delta header* and optionally |
|
1142 | adds support for storage flags in the *delta header* and optionally | |
1143 | exchanging treemanifests (enabled by setting an option on the |
|
1143 | exchanging treemanifests (enabled by setting an option on the | |
1144 | "changegroup" part in the bundle2). |
|
1144 | "changegroup" part in the bundle2). Version "4" adds support for | |
|
1145 | exchanging sidedata (additional revision metadata not part of the digest). | |||
1145 |
|
1146 | |||
1146 | Changegroups when not exchanging treemanifests consist of 3 logical |
|
1147 | Changegroups when not exchanging treemanifests consist of 3 logical | |
1147 | segments: |
|
1148 | segments: | |
@@ -1208,8 +1209,8 b' sub-topics can be accessed' | |||||
1208 | existing entry (either that the recipient already has, or previously |
|
1209 | existing entry (either that the recipient already has, or previously | |
1209 | specified in the bundle/changegroup). |
|
1210 | specified in the bundle/changegroup). | |
1210 |
|
1211 | |||
1211 |
The *delta header* is different between versions "1", "2", |
|
1212 | The *delta header* is different between versions "1", "2", "3" and "4" of | |
1212 | changegroup format. |
|
1213 | the changegroup format. | |
1213 |
|
1214 | |||
1214 | Version 1 (headerlen=80): |
|
1215 | Version 1 (headerlen=80): | |
1215 |
|
1216 | |||
@@ -1238,6 +1239,15 b' sub-topics can be accessed' | |||||
1238 | | | | | | | | |
|
1239 | | | | | | | | | |
1239 | +------------------------------------------------------------------------------+ |
|
1240 | +------------------------------------------------------------------------------+ | |
1240 |
|
1241 | |||
|
1242 | Version 4 (headerlen=103): | |||
|
1243 | ||||
|
1244 | +------------------------------------------------------------------------------+----------+ | |||
|
1245 | | | | | | | | | | |||
|
1246 | | node | p1 node | p2 node | base node | link node | flags | pflags | | |||
|
1247 | | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) | | |||
|
1248 | | | | | | | | | | |||
|
1249 | +------------------------------------------------------------------------------+----------+ | |||
|
1250 | ||||
1241 | The *delta data* consists of "chunklen - 4 - headerlen" bytes, which |
|
1251 | The *delta data* consists of "chunklen - 4 - headerlen" bytes, which | |
1242 | contain a series of *delta*s, densely packed (no separators). These deltas |
|
1252 | contain a series of *delta*s, densely packed (no separators). These deltas | |
1243 | describe a diff from an existing entry (either that the recipient already |
|
1253 | describe a diff from an existing entry (either that the recipient already | |
@@ -1278,11 +1288,24 b' sub-topics can be accessed' | |||||
1278 | delimited metadata defining an object stored elsewhere. Used by the LFS |
|
1288 | delimited metadata defining an object stored elsewhere. Used by the LFS | |
1279 | extension. |
|
1289 | extension. | |
1280 |
|
1290 | |||
|
1291 | 4096 | |||
|
1292 | Contains copy information. This revision changes files in a way that | |||
|
1293 | could affect copy tracing. This does *not* affect changegroup handling, | |||
|
1294 | but is relevant for other parts of Mercurial. | |||
|
1295 | ||||
1281 | For historical reasons, the integer values are identical to revlog version |
|
1296 | For historical reasons, the integer values are identical to revlog version | |
1282 | 1 per-revision storage flags and correspond to bits being set in this |
|
1297 | 1 per-revision storage flags and correspond to bits being set in this | |
1283 | 2-byte field. Bits were allocated starting from the most-significant bit, |
|
1298 | 2-byte field. Bits were allocated starting from the most-significant bit, | |
1284 | hence the reverse ordering and allocation of these flags. |
|
1299 | hence the reverse ordering and allocation of these flags. | |
1285 |
|
1300 | |||
|
1301 | The *pflags* (protocol flags) field holds bitwise flags affecting the | |||
|
1302 | protocol itself. They are first in the header since they may affect the | |||
|
1303 | handling of the rest of the fields in a future version. They are defined | |||
|
1304 | as such: | |||
|
1305 | ||||
|
1306 | 1 indicates whether to read a chunk of sidedata (of variable length) right | |||
|
1307 | after the revision flags. | |||
|
1308 | ||||
1286 | Changeset Segment |
|
1309 | Changeset Segment | |
1287 | ================= |
|
1310 | ================= | |
1288 |
|
1311 | |||
@@ -1303,14 +1326,14 b' sub-topics can be accessed' | |||||
1303 | Treemanifests Segment |
|
1326 | Treemanifests Segment | |
1304 | --------------------- |
|
1327 | --------------------- | |
1305 |
|
1328 | |||
1306 |
The *treemanifests segment* only exists in changegroup version "3" |
|
1329 | The *treemanifests segment* only exists in changegroup version "3" and | |
1307 |
only if the 'treemanifest' param is part of the bundle2 |
|
1330 | "4", and only if the 'treemanifest' param is part of the bundle2 | |
1308 |
(it is not possible to use changegroup version 3 o |
|
1331 | changegroup part (it is not possible to use changegroup version 3 or 4 | |
1309 |
Aside from the filenames in the *treemanifests |
|
1332 | outside of bundle2). Aside from the filenames in the *treemanifests | |
1310 |
trailing "/" character, it behaves identically to |
|
1333 | segment* containing a trailing "/" character, it behaves identically to | |
1311 |
(see below). The final sub-segment is followed by |
|
1334 | the *filelogs segment* (see below). The final sub-segment is followed by | |
1312 |
(logically, a sub-segment with filename size 0). This |
|
1335 | an *empty chunk* (logically, a sub-segment with filename size 0). This | |
1313 | to the *filelogs segment*. |
|
1336 | denotes the boundary to the *filelogs segment*. | |
1314 |
|
1337 | |||
1315 | Filelogs Segment |
|
1338 | Filelogs Segment | |
1316 | ================ |
|
1339 | ================ | |
@@ -3648,12 +3671,13 b' Sub-topic topics rendered properly' | |||||
3648 | filelogs. |
|
3671 | filelogs. | |
3649 | </p> |
|
3672 | </p> | |
3650 | <p> |
|
3673 | <p> | |
3651 |
There are |
|
3674 | There are 4 versions of changegroups: "1", "2", "3" and "4". From a | |
3652 | high-level, versions "1" and "2" are almost exactly the same, with the |
|
3675 | high-level, versions "1" and "2" are almost exactly the same, with the | |
3653 | only difference being an additional item in the *delta header*. Version |
|
3676 | only difference being an additional item in the *delta header*. Version | |
3654 | "3" adds support for storage flags in the *delta header* and optionally |
|
3677 | "3" adds support for storage flags in the *delta header* and optionally | |
3655 | exchanging treemanifests (enabled by setting an option on the |
|
3678 | exchanging treemanifests (enabled by setting an option on the | |
3656 | "changegroup" part in the bundle2). |
|
3679 | "changegroup" part in the bundle2). Version "4" adds support for exchanging | |
|
3680 | sidedata (additional revision metadata not part of the digest). | |||
3657 | </p> |
|
3681 | </p> | |
3658 | <p> |
|
3682 | <p> | |
3659 | Changegroups when not exchanging treemanifests consist of 3 logical |
|
3683 | Changegroups when not exchanging treemanifests consist of 3 logical | |
@@ -3733,8 +3757,8 b' Sub-topic topics rendered properly' | |||||
3733 | bundle/changegroup). |
|
3757 | bundle/changegroup). | |
3734 | </p> |
|
3758 | </p> | |
3735 | <p> |
|
3759 | <p> | |
3736 | The *delta header* is different between versions "1", "2", and |
|
3760 | The *delta header* is different between versions "1", "2", "3" and "4" | |
3737 |
|
|
3761 | of the changegroup format. | |
3738 | </p> |
|
3762 | </p> | |
3739 | <p> |
|
3763 | <p> | |
3740 | Version 1 (headerlen=80): |
|
3764 | Version 1 (headerlen=80): | |
@@ -3770,6 +3794,17 b' Sub-topic topics rendered properly' | |||||
3770 | +------------------------------------------------------------------------------+ |
|
3794 | +------------------------------------------------------------------------------+ | |
3771 | </pre> |
|
3795 | </pre> | |
3772 | <p> |
|
3796 | <p> | |
|
3797 | Version 4 (headerlen=103): | |||
|
3798 | </p> | |||
|
3799 | <pre> | |||
|
3800 | +------------------------------------------------------------------------------+----------+ | |||
|
3801 | | | | | | | | | | |||
|
3802 | | node | p1 node | p2 node | base node | link node | flags | pflags | | |||
|
3803 | | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) | (1 byte) | | |||
|
3804 | | | | | | | | | | |||
|
3805 | +------------------------------------------------------------------------------+----------+ | |||
|
3806 | </pre> | |||
|
3807 | <p> | |||
3773 | The *delta data* consists of "chunklen - 4 - headerlen" bytes, which contain a |
|
3808 | The *delta data* consists of "chunklen - 4 - headerlen" bytes, which contain a | |
3774 | series of *delta*s, densely packed (no separators). These deltas describe a diff |
|
3809 | series of *delta*s, densely packed (no separators). These deltas describe a diff | |
3775 | from an existing entry (either that the recipient already has, or previously |
|
3810 | from an existing entry (either that the recipient already has, or previously | |
@@ -3808,6 +3843,8 b' Sub-topic topics rendered properly' | |||||
3808 | <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents). |
|
3843 | <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents). | |
3809 | <dt>8192 |
|
3844 | <dt>8192 | |
3810 | <dd>Externally stored. The revision fulltext contains "key:value" "\n" delimited metadata defining an object stored elsewhere. Used by the LFS extension. |
|
3845 | <dd>Externally stored. The revision fulltext contains "key:value" "\n" delimited metadata defining an object stored elsewhere. Used by the LFS extension. | |
|
3846 | <dt>4096 | |||
|
3847 | <dd>Contains copy information. This revision changes files in a way that could affect copy tracing. This does *not* affect changegroup handling, but is relevant for other parts of Mercurial. | |||
3811 | </dl> |
|
3848 | </dl> | |
3812 | <p> |
|
3849 | <p> | |
3813 | For historical reasons, the integer values are identical to revlog version 1 |
|
3850 | For historical reasons, the integer values are identical to revlog version 1 | |
@@ -3815,6 +3852,15 b' Sub-topic topics rendered properly' | |||||
3815 | field. Bits were allocated starting from the most-significant bit, hence the |
|
3852 | field. Bits were allocated starting from the most-significant bit, hence the | |
3816 | reverse ordering and allocation of these flags. |
|
3853 | reverse ordering and allocation of these flags. | |
3817 | </p> |
|
3854 | </p> | |
|
3855 | <p> | |||
|
3856 | The *pflags* (protocol flags) field holds bitwise flags affecting the protocol | |||
|
3857 | itself. They are first in the header since they may affect the handling of the | |||
|
3858 | rest of the fields in a future version. They are defined as such: | |||
|
3859 | </p> | |||
|
3860 | <dl> | |||
|
3861 | <dt>1 indicates whether to read a chunk of sidedata (of variable length) right | |||
|
3862 | <dd>after the revision flags. | |||
|
3863 | </dl> | |||
3818 | <h2>Changeset Segment</h2> |
|
3864 | <h2>Changeset Segment</h2> | |
3819 | <p> |
|
3865 | <p> | |
3820 | The *changeset segment* consists of a single *delta group* holding |
|
3866 | The *changeset segment* consists of a single *delta group* holding | |
@@ -3832,9 +3878,9 b' Sub-topic topics rendered properly' | |||||
3832 | </p> |
|
3878 | </p> | |
3833 | <h3>Treemanifests Segment</h3> |
|
3879 | <h3>Treemanifests Segment</h3> | |
3834 | <p> |
|
3880 | <p> | |
3835 |
The *treemanifests segment* only exists in changegroup version "3" |
|
3881 | The *treemanifests segment* only exists in changegroup version "3" and "4", | |
3836 | only if the 'treemanifest' param is part of the bundle2 changegroup part |
|
3882 | and only if the 'treemanifest' param is part of the bundle2 changegroup part | |
3837 | (it is not possible to use changegroup version 3 outside of bundle2). |
|
3883 | (it is not possible to use changegroup version 3 or 4 outside of bundle2). | |
3838 | Aside from the filenames in the *treemanifests segment* containing a |
|
3884 | Aside from the filenames in the *treemanifests segment* containing a | |
3839 | trailing "/" character, it behaves identically to the *filelogs segment* |
|
3885 | trailing "/" character, it behaves identically to the *filelogs segment* | |
3840 | (see below). The final sub-segment is followed by an *empty chunk* (logically, |
|
3886 | (see below). The final sub-segment is followed by an *empty chunk* (logically, |
@@ -355,11 +355,11 b' lfs content, and the extension enabled.' | |||||
355 | # LFS required- both lfs and non-lfs revlogs have 0x2000 flag |
|
355 | # LFS required- both lfs and non-lfs revlogs have 0x2000 flag | |
356 | *** runcommand debugprocessors lfs.bin -R ../server |
|
356 | *** runcommand debugprocessors lfs.bin -R ../server | |
357 | registered processor '0x8000' |
|
357 | registered processor '0x8000' | |
358 |
registered processor '0x |
|
358 | registered processor '0x1000' | |
359 | registered processor '0x2000' |
|
359 | registered processor '0x2000' | |
360 | *** runcommand debugprocessors nonlfs2.txt -R ../server |
|
360 | *** runcommand debugprocessors nonlfs2.txt -R ../server | |
361 | registered processor '0x8000' |
|
361 | registered processor '0x8000' | |
362 |
registered processor '0x |
|
362 | registered processor '0x1000' | |
363 | registered processor '0x2000' |
|
363 | registered processor '0x2000' | |
364 | *** runcommand config extensions --cwd ../server |
|
364 | *** runcommand config extensions --cwd ../server | |
365 | extensions.debugprocessors=$TESTTMP/debugprocessors.py |
|
365 | extensions.debugprocessors=$TESTTMP/debugprocessors.py | |
@@ -368,7 +368,7 b' lfs content, and the extension enabled.' | |||||
368 | # LFS not enabled- revlogs don't have 0x2000 flag |
|
368 | # LFS not enabled- revlogs don't have 0x2000 flag | |
369 | *** runcommand debugprocessors nonlfs3.txt |
|
369 | *** runcommand debugprocessors nonlfs3.txt | |
370 | registered processor '0x8000' |
|
370 | registered processor '0x8000' | |
371 |
registered processor '0x |
|
371 | registered processor '0x1000' | |
372 | *** runcommand config extensions |
|
372 | *** runcommand config extensions | |
373 | extensions.debugprocessors=$TESTTMP/debugprocessors.py |
|
373 | extensions.debugprocessors=$TESTTMP/debugprocessors.py | |
374 |
|
374 | |||
@@ -411,11 +411,11 b' lfs content, and the extension enabled.' | |||||
411 | # LFS enabled- both lfs and non-lfs revlogs have 0x2000 flag |
|
411 | # LFS enabled- both lfs and non-lfs revlogs have 0x2000 flag | |
412 | *** runcommand debugprocessors lfs.bin -R ../server |
|
412 | *** runcommand debugprocessors lfs.bin -R ../server | |
413 | registered processor '0x8000' |
|
413 | registered processor '0x8000' | |
414 |
registered processor '0x |
|
414 | registered processor '0x1000' | |
415 | registered processor '0x2000' |
|
415 | registered processor '0x2000' | |
416 | *** runcommand debugprocessors nonlfs2.txt -R ../server |
|
416 | *** runcommand debugprocessors nonlfs2.txt -R ../server | |
417 | registered processor '0x8000' |
|
417 | registered processor '0x8000' | |
418 |
registered processor '0x |
|
418 | registered processor '0x1000' | |
419 | registered processor '0x2000' |
|
419 | registered processor '0x2000' | |
420 | *** runcommand config extensions --cwd ../server |
|
420 | *** runcommand config extensions --cwd ../server | |
421 | extensions.debugprocessors=$TESTTMP/debugprocessors.py |
|
421 | extensions.debugprocessors=$TESTTMP/debugprocessors.py | |
@@ -424,7 +424,7 b' lfs content, and the extension enabled.' | |||||
424 | # LFS enabled without requirement- revlogs have 0x2000 flag |
|
424 | # LFS enabled without requirement- revlogs have 0x2000 flag | |
425 | *** runcommand debugprocessors nonlfs3.txt |
|
425 | *** runcommand debugprocessors nonlfs3.txt | |
426 | registered processor '0x8000' |
|
426 | registered processor '0x8000' | |
427 |
registered processor '0x |
|
427 | registered processor '0x1000' | |
428 | registered processor '0x2000' |
|
428 | registered processor '0x2000' | |
429 | *** runcommand config extensions |
|
429 | *** runcommand config extensions | |
430 | extensions.debugprocessors=$TESTTMP/debugprocessors.py |
|
430 | extensions.debugprocessors=$TESTTMP/debugprocessors.py | |
@@ -433,7 +433,7 b' lfs content, and the extension enabled.' | |||||
433 | # LFS disabled locally- revlogs don't have 0x2000 flag |
|
433 | # LFS disabled locally- revlogs don't have 0x2000 flag | |
434 | *** runcommand debugprocessors nonlfs.txt -R ../nonlfs |
|
434 | *** runcommand debugprocessors nonlfs.txt -R ../nonlfs | |
435 | registered processor '0x8000' |
|
435 | registered processor '0x8000' | |
436 |
registered processor '0x |
|
436 | registered processor '0x1000' | |
437 | *** runcommand config extensions --cwd ../nonlfs |
|
437 | *** runcommand config extensions --cwd ../nonlfs | |
438 | extensions.debugprocessors=$TESTTMP/debugprocessors.py |
|
438 | extensions.debugprocessors=$TESTTMP/debugprocessors.py | |
439 | extensions.lfs=! |
|
439 | extensions.lfs=! |
General Comments 0
You need to be logged in to leave comments.
Login now