The bug was reported by a team that hit it in production on git 2.43. They found a ref pointing at a commit that no longer existed, and it reproduces on master. Repack scans for .keep files to decide which packs are redundant. It then spawns pack-objects with --honor-pack-keep, which scans again.

If an index-pack --keep finishes in between, for example a push migrating its quarantine or a fetch, it installs a .keep next to a pack repack has already decided to delete. Pack-objects sees the .keep and leaves that pack's objects out of the replacement. Repack deletes the pack from its earlier list anyway, because repack_remove_redundant_pack() passes force_delete, which skips the .keep check. The command still exits successfully.

The patches in the series cover several related changes. Repack can read the --keep-pack names from a file, since many names can overflow ARG_MAX or Windows' 32,767-character command-line limit. pack-objects sorts the kept-pack list instead of rescanning it for every pack; the author measured 11 seconds for 20,000 packs against 20,000 names with the old scan. Another patch fixes a stale kept-pack cache when writing cruft packs with an expiry. A last patch changes --stdin-packs=follow so a --keep-pack pack is not treated as closed under reachability.

On the review side, Junio C Hamano suggested waiting for the ps/odb-files-alternates topic to settle and then rebasing onto a synthetic base that merges it into master. He noted that Karthik Nayak had read the first round of that topic and approved the current iteration, and said it would benefit from another reviewer. Qin ShiCheng agreed to hold off and send v4 on top of master with that topic merged, and to say so in the cover letter.