From: "qeesung via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Patrick Steinhardt <ps@pks.im>, Taylor Blau <ttaylorr@openai.com>,
Junio C Hamano <gitster@pobox.com>,
Justin Tobler <jltobler@gmail.com>, qeesung <qeesung@live.com>
Subject: [PATCH 0/6] repack: don't lose objects to a ".keep" that appears mid-run
Date: Mon, 14 Sep 2026 11:31:17 +0000 [thread overview]
Message-ID: <pull.2219.git.1789385483.gitgitgadget@gmail.com> (raw)
A concurrent push can make "git repack -d" delete a pack whose objects were
never copied anywhere, and exit 0. We hit this in production: a ref pointing
at a commit that no longer exists, on git 2.43, and it reproduces on master.
What happens:
* repack scans for ".keep" files and decides which packs to delete, then
spawns pack-objects with --honor-pack-keep, which scans again;
* in between, a push of content identical to an earlier one finishes
migrating its quarantine. Its pack is a duplicate and is dropped, but its
".keep" is linked into place, onto the old pack;
* pack-objects sees that ".keep" and leaves the pack's objects out; repack
deletes the pack by its earlier list, with force_delete.
Two things are wrong, and each is fixed on its own:
* 1/6: receive-pack removes a ".keep" it never installed -- the one it
linked onto somebody else's pack, or a foreign one when its own push was
rejected before any migration. Only remove a ".keep" that carries our own
message.
* 6/6: repack and pack-objects each scan for ".keep" files. Hand
pack-objects the snapshot repack took at startup instead.
Patches 2-5 are what 6/6 needs to be safe:
* 2/6: under --stdin-packs=follow, a --keep-pack pack stops the traversal
like a "^" pack; on-disk ".keep" packs never did.
* 3/6: the cruft walk goes by a stale kept-pack cache, which
--honor-pack-keep happened to mask. Pre-existing, reproducible today.
* 4/6: look --keep-pack names up in a sorted list; it gets long.
* 5/6: --keep-pack-from-file, since a repository can have more kept packs
than fit on a command line (32K characters on Windows).
Every fix comes with a test that fails without it; the race itself is
reproduced in t7703 by having a ".keep" appear as pack-objects starts. The
full suite passes, and the series merges cleanly into next and seen.
Qin ShiCheng (6):
odb: don't remove a ".keep" we never installed
pack-objects: keep --keep-pack open when following
pack-objects: reset kept-pack cache for cruft walk
pack-objects: sort --keep-pack list for lookup
pack-objects: add --keep-pack-from-file
repack: tell pack-objects which packs are kept
Documentation/git-pack-objects.adoc | 8 +++
builtin/pack-objects.c | 71 +++++++++++++++++----
builtin/repack.c | 15 +++++
object-file.c | 95 ++++++++++++++++++++++-------
odb/source-packed.h | 3 +-
packfile.c | 9 ++-
packfile.h | 7 +++
repack-filtered.c | 3 -
repack.c | 34 ++++++++++-
repack.h | 17 +++++-
t/t5329-pack-objects-cruft.sh | 40 ++++++++++++
t/t5331-pack-objects-stdin.sh | 87 ++++++++++++++++++++++++++
t/t5547-push-quarantine.sh | 52 ++++++++++++++++
t/t7700-repack.sh | 43 +++++++++++++
t/t7703-repack-geometric.sh | 72 ++++++++++++++++++++++
tempfile.c | 12 ++++
tempfile.h | 9 +++
17 files changed, 533 insertions(+), 44 deletions(-)
base-commit: 3cb9185f65410273787f74333cc027d2ea5daada
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2219%2Fqeesung%2Frepack-kept-packs-snapshot-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2219/qeesung/repack-kept-packs-snapshot-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/2219
--
gitgitgadget
next reply other threads:[~2026-09-14 11:31 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-14 11:31 qeesung via GitGitGadget [this message]
2026-09-14 11:31 ` [PATCH 1/6] odb: don't remove a ".keep" we never installed Qin ShiCheng via GitGitGadget
2026-09-15 18:25 ` Justin Tobler
2026-09-16 6:01 ` Qin ShiCheng
2026-09-14 11:31 ` [PATCH 2/6] pack-objects: keep --keep-pack open when following Qin ShiCheng via GitGitGadget
2026-09-14 11:31 ` [PATCH 3/6] pack-objects: reset kept-pack cache for cruft walk Qin ShiCheng via GitGitGadget
2026-09-14 11:31 ` [PATCH 4/6] pack-objects: sort --keep-pack list for lookup Qin ShiCheng via GitGitGadget
2026-09-14 11:31 ` [PATCH 5/6] pack-objects: add --keep-pack-from-file Qin ShiCheng via GitGitGadget
2026-09-14 11:31 ` [PATCH 6/6] repack: tell pack-objects which packs are kept Qin ShiCheng via GitGitGadget
2026-09-18 3:03 ` [PATCH v2 0/5] repack: don't lose objects to a ".keep" that appears mid-run qeesung via GitGitGadget
2026-09-18 3:03 ` [PATCH v2 1/5] pack-objects: keep --keep-pack open when following Qin ShiCheng via GitGitGadget
2026-09-18 3:03 ` [PATCH v2 2/5] pack-objects: reset kept-pack cache for cruft walk Qin ShiCheng via GitGitGadget
2026-09-22 22:31 ` Junio C Hamano
2026-09-23 3:08 ` Qin ShiCheng
2026-09-23 17:45 ` Junio C Hamano
2026-09-18 3:03 ` [PATCH v2 3/5] pack-objects: sort --keep-pack list for lookup Qin ShiCheng via GitGitGadget
2026-09-18 3:03 ` [PATCH v2 4/5] pack-objects: add --keep-pack-from-file Qin ShiCheng via GitGitGadget
2026-09-18 3:03 ` [PATCH v2 5/5] repack: tell pack-objects which packs are kept Qin ShiCheng via GitGitGadget
2026-10-08 9:52 ` [PATCH v3 0/5] repack: don't lose objects to a ".keep" that appears mid-run qeesung via GitGitGadget
2026-10-08 9:52 ` [PATCH v3 1/5] pack-objects: keep --keep-pack open when following Qin ShiCheng via GitGitGadget
2026-10-08 9:52 ` [PATCH v3 2/5] pack-objects: reset kept-pack cache for cruft walk Qin ShiCheng via GitGitGadget
2026-10-08 9:52 ` [PATCH v3 3/5] pack-objects: sort --keep-pack list for lookup Qin ShiCheng via GitGitGadget
2026-10-08 9:52 ` [PATCH v3 4/5] pack-objects: add --keep-pack-from-file Qin ShiCheng via GitGitGadget
2026-10-08 9:52 ` [PATCH v3 5/5] repack: tell pack-objects which packs are kept Qin ShiCheng via GitGitGadget
2026-10-08 19:19 ` [PATCH v3 0/5] repack: don't lose objects to a ".keep" that appears mid-run Junio C Hamano
2026-10-09 3:07 ` Qin ShiCheng
2026-10-09 15:11 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.2219.git.1789385483.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jltobler@gmail.com \
--cc=ps@pks.im \
--cc=qeesung@live.com \
--cc=ttaylorr@openai.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.