]> git.ipfire.org Git - thirdparty/git.git/commit
pack-objects: introduce '--stdin-packs=follow-reachable'
authorTaylor Blau <me@ttaylorr.com>
Fri, 26 Jun 2026 19:02:37 +0000 (15:02 -0400)
committerJunio C Hamano <gitster@pobox.com>
Fri, 26 Jun 2026 21:54:55 +0000 (14:54 -0700)
commitec0165a0cd79f6391dbb546a065db1695db0aa91
tree4e320bf96141ed3ad2e66e856b6bb34669d634a5
parent806cd59ba235c0b19261019c039a22392cc6fc04
pack-objects: introduce '--stdin-packs=follow-reachable'

Introduce a new '--stdin-packs=follow-reachable' mode. Like
'--stdin-packs=follow', this mode recognizes the '!' (excluded-open)
pack prefix and halts at '^' (excluded-closed) packs.

Unlike 'follow', which eagerly includes all objects from listed packs
and then walks reachability to rescue additional objects, the new
'follow-reachable' mode uses reference tips as its traversal starting
points and only includes objects that are both reachable AND belong to
an included pack (or are reachable from a commit or tag in one):

 - Objects in included packs: added to the output if reachable.

 - Objects reachable from included-pack commits but in unknown packs:
   added to the output (rescued).

 - Objects in excluded-open ('!') packs: not included, but the traversal
   continues through them.

 - Objects in excluded-closed ('^') packs: not included, and the
   traversal halts.

The implementation uses a two-phase approach:

 1. In the first phase, commits and tags in included packs (and loose,
    when --unpacked is given) are marked with a flag bit
    (IN_INCLUDED_PACK). A commit-only walk from ref tips then identifies
    which marked objects are reachable, halting at excluded-closed
    packs.

 2. In the second phase, every reachable marked object (from the
    previous step) becomes a tip for a full object traversal whose
    `show_object_pack_hint()` and `show_commit_pack_hint()` callbacks
    add discovered objects (obeying the usual constraints imposed by
    `want_object_in_pack()`).

When '--unpacked' is given, reachable loose objects are included in the
output while unreachable loose objects are left alone. This is achieved
by marking loose commits and tags with IN_INCLUDED_PACK during the first
phase, so the pre-walk discovers them naturally.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-pack-objects.adoc
builtin/pack-objects.c
t/t5331-pack-objects-stdin.sh