close
Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: git/git
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a636d395ff0b0ccecb4569c0fc80f7c55f2e5f2e
Choose a base ref
...
head repository: git/git
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5ee86c273bfc83fa432910a13c6ce28b74361896
Choose a head ref
  • 9 commits
  • 6 files changed
  • 1 contributor

Commits on Jun 23, 2025

  1. pack-objects: use standard option incompatibility functions

    pack-objects has a handful of explicit checks for pairs of command-line
    options which are mutually incompatible. Many of these pre-date
    a699367 (i18n: factorize more 'incompatible options' messages,
    2022-01-31).
    
    Convert the explicit checks into die_for_incompatible_opt2() calls,
    which simplifies the implementation and standardizes pack-objects'
    output when given incompatible options (e.g., --stdin-packs with
    --filter gives different output than --keep-unreachable with
    --unpack-unreachable).
    
    There is one minor piece of test fallout in t5331 that expects the old
    format, which has been corrected.
    
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    798ddd9 View commit details
    Browse the repository at this point in the history
  2. pack-objects: limit scope in 'add_object_entry_from_pack()'

    In add_object_entry_from_pack() we declare 'revs' (given to us through
    the miscellaneous context argument) earlier in the "if (p)" conditional
    than is necessary.  Move it down as far as it can go to reduce its
    scope.
    
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    9809d4a View commit details
    Browse the repository at this point in the history
  3. pack-objects: factor out handling '--stdin-packs'

    At the bottom of cmd_pack_objects() we check which mode the command is
    running in (e.g., generating a cruft pack, handling '--stdin-packs',
    using the internal rev-list, etc.) and handle the mode appropriately.
    
    The '--stdin-packs' case is handled inline (dating back to its
    introduction in 339bce2 (builtin/pack-objects.c: add '--stdin-packs'
    option, 2021-02-22)) since it is relatively short. Extract the body of
    "if (stdin_packs)" into its own function to prepare for the
    implementation to become lengthier in a following commit.
    
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    67e1a78 View commit details
    Browse the repository at this point in the history
  4. pack-objects: declare 'rev_info' for '--stdin-packs' earlier

    Once 'read_packs_list_from_stdin()' has called for_each_object_in_pack()
    on each of the input packs, we do a reachability traversal to discover
    names for any objects we picked up so we can generate name hash values
    and hopefully get higher quality deltas as a result.
    
    A future commit will change the purpose of this reachability traversal
    to find and pack objects which are reachable from commits in the input
    packs, but are packed in an unknown (not included nor excluded) pack.
    
    Extract the code which initializes and performs the reachability
    traversal to take place in the caller, not the callee, which prepares us
    to share this code for the '--unpacked' case (see the function
    add_unreachable_loose_objects() for more details).
    
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    97ec432 View commit details
    Browse the repository at this point in the history
  5. pack-objects: perform name-hash traversal for unpacked objects

    With '--unpacked', pack-objects adds loose objects (which don't appear
    in any of the excluded packs from '--stdin-packs') to the output pack
    without considering them as reachability tips for the name-hash
    traversal.
    
    This was an oversight in the original implementation of '--stdin-packs',
    since the code which enumerates and adds loose objects to the output
    pack (`add_unreachable_loose_objects()`) did not have access to the
    'rev_info' struct found in `read_packs_list_from_stdin()`.
    
    Excluding unpacked objects from that traversal doesn't affect the
    correctness of the resulting pack, but it does make it harder to
    discover good deltas for loose objects.
    
    Now that the 'rev_info' struct is declared outside of
    `read_packs_list_from_stdin()`, we can pass it to
    `add_objects_in_unpacked_packs()` and add any loose objects as tips to
    the above-mentioned traversal, in theory producing slightly tighter
    packs as a result.
    
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    d6220cc View commit details
    Browse the repository at this point in the history
  6. pack-objects: fix typo in 'show_object_pack_hint()'

    Noticed-by: Elijah Newren <newren@gmail.com>
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    8ed5d87 View commit details
    Browse the repository at this point in the history
  7. pack-objects: swap 'show_{object,commit}_pack_hint'

    show_commit_pack_hint() has heretofore been a noop, so its position
    within its compilation unit only needs to appear before its first use.
    
    But the following commit will sometimes have `show_commit_pack_hint()`
    call `show_object_pack_hint()`, so reorder the former to appear after
    the latter to minimize the code movement in that patch.
    
    Suggested-by: Elijah Newren <newren@gmail.com>
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    63195f0 View commit details
    Browse the repository at this point in the history
  8. pack-objects: introduce '--stdin-packs=follow'

    When invoked with '--stdin-packs', pack-objects will generate a pack
    which contains the objects found in the "included" packs, less any
    objects from "excluded" packs.
    
    Packs that exist in the repository but weren't specified as either
    included or excluded are in practice treated like the latter, at least
    in the sense that pack-objects won't include objects from those packs.
    This behavior forces us to include any cruft pack(s) in a repository's
    multi-pack index for the reasons described in ddee370
    (builtin/repack.c: add cruft packs to MIDX during geometric repack,
    2022-05-20).
    
    The full details are in ddee370, but the gist is if you
    have a once-unreachable object in a cruft pack which later becomes
    reachable via one or more commits in a pack generated with
    '--stdin-packs', you *have* to include that object in the MIDX via the
    copy in the cruft pack, otherwise we cannot generate reachability
    bitmaps for any commits which reach that object.
    
    Note that the traversal here is best-effort, similar to the existing
    traversal which provides name-hash hints. This means that the object
    traversal may hand us back a blob that does not actually exist. We
    *won't* see missing trees/commits with 'ignore_missing_links' because:
    
     - missing commit parents are discarded at the commit traversal stage by
       revision.c::process_parents()
    
     - missing tag objects are discarded by revision.c::handle_commit()
    
     - missing tree objects are discarded by the list-objects code in
       list-objects.c::process_tree()
    
    But we have to handle potentially-missing blobs specially by making a
    separate check to ensure they exist in the repository. Failing to do so
    would mean that we'd add an object to the packing list which doesn't
    actually exist, rendering us unable to write out the pack.
    
    This prepares us for new repacking behavior which will "resurrect"
    objects found in cruft or otherwise unspecified packs when generating
    new packs. In the context of geometric repacking, this may be used to
    maintain a sequence of geometrically-repacked packs, the union of which
    is closed under reachability, even in the case described earlier.
    
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    cd846ba View commit details
    Browse the repository at this point in the history
  9. repack: exclude cruft pack(s) from the MIDX where possible

    In ddee370 (builtin/repack.c: add cruft packs to MIDX during
    geometric repack, 2022-05-20), repack began adding cruft pack(s) to the
    MIDX with '--write-midx' to ensure that the resulting MIDX was always
    closed under reachability in order to generate reachability bitmaps.
    
    While the previous patch added the '--stdin-packs=follow' option to
    pack-objects, it is not yet on by default. Given that, suppose you have
    a once-unreachable object packed in a cruft pack, which later becomes
    reachable from one or more objects in a geometrically repacked pack.
    That once-unreachable object *won't* appear in the new pack, since the
    cruft pack was not specified as included or excluded when the
    geometrically repacked pack was created with 'pack-objects
    --stdin-packs' (*not* '--stdin-packs=follow', which is not on). If that
    new pack is included in a MIDX without the cruft pack, then trying to
    generate bitmaps for that MIDX may fail. This happens when the bitmap
    selection process picks one or more commits which reach the
    once-unreachable objects.
    
    To mitigate this failure mode, commit ddee370 ensures that the MIDX
    will be closed under reachability by including cruft pack(s). If cruft
    pack(s) were not included, we would fail to generate a MIDX bitmap. But
    ddee370 alludes to the fact that this is sub-optimal by saying
    
        [...] it's desirable to avoid including cruft packs in the MIDX
        because it causes the MIDX to store a bunch of objects which are
        likely to get thrown away.
    
    , which is true, but hides an even larger problem. If repositories
    rarely prune their unreachable objects and/or have many of them, the
    MIDX must keep track of a large number of objects which bloats the MIDX
    and slows down object lookup.
    
    This is doubly unfortunate because the vast majority of objects in cruft
    pack(s) are unlikely to be read. But any object lookups that go through
    the MIDX must binary search over them anyway, slowing down object
    lookups using the MIDX.
    
    This patch causes geometrically-repacked packs to contain a copy of any
    once-unreachable object(s) with 'git pack-objects --stdin-packs=follow',
    allowing us to avoid including any cruft packs in the MIDX. This is
    because a sequence of geometrically-repacked packs that were all
    generated with '--stdin-packs=follow' are guaranteed to have their union
    be closed under reachability.
    
    Note that you cannot guarantee that a collection of packs is closed
    under reachability if not all of them were generated with "following" as
    above. One tell-tale sign that not all geometrically-repacked packs in
    the MIDX were generated with "following" is to see if there is a pack in
    the existing MIDX that is not going to be somehow represented (either
    verbatim or as part of a geometric rollup) in the new MIDX.
    
    If there is, then starting to generate packs with "following" during
    geometric repacking won't work, since it's open to the same race as
    described above.
    
    But if you're starting from scratch (e.g., building the first MIDX after
    an all-into-one '--cruft' repack), then you can guarantee that the union
    of subsequently generated packs from geometric repacking *is* closed
    under reachability.
    
    (One exception here is when "starting from scratch" results in a noop
    repack, e.g., because the non-cruft pack(s) in a repository already form
    a geometric progression. Since we can't tell whether or not those were
    generated with '--stdin-packs=follow', they may depend on
    once-unreachable objects, so we have to include the cruft pack in the
    MIDX in this case.)
    
    Detect when this is the case and avoid including cruft packs in the MIDX
    where possible. The existing behavior remains the default, and the new
    behavior is available with the config 'repack.midxMustIncludeCruft' set
    to 'false'.
    
    Signed-off-by: Taylor Blau <me@ttaylorr.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    ttaylorr authored and gitster committed Jun 23, 2025
    Configuration menu
    Copy the full SHA
    5ee86c2 View commit details
    Browse the repository at this point in the history
Loading