This file is indexed.

/usr/share/mercurial/help/internals/changegroups.txt is in mercurial-common 3.7.3-1ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
Changegroups
============

Changegroups are representations of repository revlog data, specifically
the changelog, manifest, and filelogs.

There are 3 versions of changegroups: ``1``, ``2``, and ``3``. From a
high-level, versions ``1`` and ``2`` are almost exactly the same, with
the only difference being a header on entries in the changeset
segment. Version ``3`` adds support for exchanging treemanifests and
includes revlog flags in the delta header.

Changegroups consists of 3 logical segments::

   +---------------------------------+
   |           |          |          |
   | changeset | manifest | filelogs |
   |           |          |          |
   +---------------------------------+

The principle building block of each segment is a *chunk*. A *chunk*
is a framed piece of data::

   +---------------------------------------+
   |           |                           |
   |  length   |           data            |
   | (32 bits) |       <length> bytes      |
   |           |                           |
   +---------------------------------------+

Each chunk starts with a 32-bit big-endian signed integer indicating
the length of the raw data that follows.

There is a special case chunk that has 0 length (``0x00000000``). We
call this an *empty chunk*.

Delta Groups
------------

A *delta group* expresses the content of a revlog as a series of deltas,
or patches against previous revisions.

Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
to signal the end of the delta group::

  +------------------------------------------------------------------------+
  |                |             |               |             |           |
  | chunk0 length  | chunk0 data | chunk1 length | chunk1 data |    0x0    |
  |   (32 bits)    |  (various)  |   (32 bits)   |  (various)  | (32 bits) |
  |                |             |               |             |           |
  +------------------------------------------------------------+-----------+

Each *chunk*'s data consists of the following::

  +-----------------------------------------+
  |              |              |           |
  | delta header | mdiff header |   delta   |
  |  (various)   |  (12 bytes)  | (various) |
  |              |              |           |
  +-----------------------------------------+

The *length* field is the byte length of the remaining 3 logical pieces
of data. The *delta* is a diff from an existing entry in the changelog.

The *delta header* is different between versions ``1``, ``2``, and
``3`` of the changegroup format.

Version 1::

   +------------------------------------------------------+
   |            |             |             |             |
   |    node    |   p1 node   |   p2 node   |  link node  |
   | (20 bytes) |  (20 bytes) |  (20 bytes) |  (20 bytes) |
   |            |             |             |             |
   +------------------------------------------------------+

Version 2::

   +------------------------------------------------------------------+
   |            |             |             |            |            |
   |    node    |   p1 node   |   p2 node   | base node  | link node  |
   | (20 bytes) |  (20 bytes) |  (20 bytes) | (20 bytes) | (20 bytes) |
   |            |             |             |            |            |
   +------------------------------------------------------------------+

Version 3::

   +------------------------------------------------------------------------------+
   |            |             |             |            |            |           |
   |    node    |   p1 node   |   p2 node   | base node  | link node  | flags     |
   | (20 bytes) |  (20 bytes) |  (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
   |            |             |             |            |            |           |
   +------------------------------------------------------------------------------+

The *mdiff header* consists of 3 32-bit big-endian signed integers
describing offsets at which to apply the following delta content::

   +-------------------------------------+
   |           |            |            |
   |  offset   | old length | new length |
   | (32 bits) |  (32 bits) |  (32 bits) |
   |           |            |            |
   +-------------------------------------+

In version 1, the delta is always applied against the previous node from
the changegroup or the first parent if this is the first entry in the
changegroup.

In version 2, the delta base node is encoded in the entry in the
changegroup. This allows the delta to be expressed against any parent,
which can result in smaller deltas and more efficient encoding of data.

Changeset Segment
-----------------

The *changeset segment* consists of a single *delta group* holding
changelog data. It is followed by an *empty chunk* to denote the
boundary to the *manifests segment*.

Manifest Segment
----------------

The *manifest segment* consists of a single *delta group* holding
manifest data. It is followed by an *empty chunk* to denote the boundary
to the *filelogs segment*.

Filelogs Segment
----------------

The *filelogs* segment consists of multiple sub-segments, each
corresponding to an individual file whose data is being described::

   +--------------------------------------+
   |          |          |          |     |
   | filelog0 | filelog1 | filelog2 | ... |
   |          |          |          |     |
   +--------------------------------------+

In version ``3`` of the changegroup format, filelogs may include
directory logs when treemanifests are in use. directory logs are
identified by having a trailing '/' on their filename (see below).

The final filelog sub-segment is followed by an *empty chunk* to denote
the end of the segment and the overall changegroup.

Each filelog sub-segment consists of the following::

   +------------------------------------------+
   |               |            |             |
   | filename size |  filename  | delta group |
   |   (32 bits)   |  (various) |  (various)  |
   |               |            |             |
   +------------------------------------------+

That is, a *chunk* consisting of the filename (not terminated or padded)
followed by N chunks constituting the *delta group* for this file.