in order to implement
multi-pack reuse over a set of packfiles as described above.
Specifically, the `BTMP` chunk encodes three pieces of information (all
32-bit unsigned integers in network byte-order) for each packfile `p`
that is stored in the MIDX, as follows:
`bitmap_pos`:: The first bit position (in pseudo-pack order) in the
multi-pack index's reachability bitmap occupied by an object from `p`.
`bitmap_nr`:: The number of bit positions (including the one at
`bitmap_pos`) that encode objects from that pack `p`.
For example, the `BTMP` chunk corresponding to the above example (with
packs ``a'', ``b'', and ``c'') would look like:
[cols="1,2,2"]
|===
| |`bitmap_pos` |`bitmap_nr`
|packfile ``a''
|`0`
|`10`
|packfile ``b''
|`10`
|`15`
|packfile ``c''
|`25`
|`20`
|===
With this information in place, we can treat each packfile as
individually reusable in the same fashion as verbatim pack reuse is
performed on individual packs prior to the implementation of the `BTMP`
chunk.
== cruft packs
The cruft packs feature offer an alternative to Git's traditional mechanism of
removing unreachable objects. This document provides an overview of Git's
pruning mechanism, and how a cruft pack can be used instead to accomplish the
same.
=== Background
To remove unreachable objects from your repository, Git offers `git repack -Ad`
(see linkgit:git-repack[1]). Quoting from the documentation:
----
[...] unreachable objects in a previous pack become loose, unpacked objects,
instead of being left in the old pack. [...] loose unreachable objects will be
pruned according to normal expiry rules with the next 'git gc' invocation.
----
Unreachable objects aren't removed immediately, since doing so could race with
an incoming push which may reference an object which is about to be deleted.
Instead, those unreachable objects are stored as loose objects and stay that way
until they are older than the expiration window, at which point they are removed
by linkgit:git-prune[1].
Git must store these unreachable objects loose in order to keep track of their
per-object mtimes. If these unreachable objects were written into one big pack,
then either freshening that pack (because an object contained within it was
re-written) or creating a new pack of unreachable objects would cause the pack's
mtime to get updated, and the objects within it would never leave the expiration
window. Instead, objects are stored loose in order to keep track of the
individual object mtimes and avoid a situation where all cruft objects are
freshened at once.
This can lead to undesirable situations when a repository contains many
unreachable objects which have not yet left the