aboutsummaryrefslogtreecommitdiff
path: root/t
AgeCommit message (Collapse)Author
7 daysMerge branch 'jt/index-fd-wo-repo-regression-fix-maint'Junio C Hamano
During Git 2.52 timeframe, we broke streaming computation of object hash outside a repository, which has been corrected. * jt/index-fd-wo-repo-regression-fix-maint: object-file: avoid ODB transaction when not writing objects
7 daysMerge branch 'tc/replay-ref'Junio C Hamano
The experimental `git replay` command learned the `--ref=<ref>` option to allow specifying which ref to update, overriding the default behavior. * tc/replay-ref: replay: allow to specify a ref with option --ref replay: use stuck form in documentation and help message builtin/replay: mark options as not negatable
7 daysMerge branch 'ng/add-files-to-cache-wo-rename'Junio C Hamano
add_files_to_cache() used diff_files() to detect only the paths that are different between the index and the working tree and add them, which does not need rename detection, which interfered with unnecessary conflicts. * ng/add-files-to-cache-wo-rename: read-cache: disable renames in add_files_to_cache
7 daysMerge branch 'ss/t7004-unhide-git-failures'Junio C Hamano
Test clean-up. * ss/t7004-unhide-git-failures: t7004: replace wc -l with modern test helpers
7 dayst1800: add &&-chains to test helper functionsAdrian Ratiu
Add the missing &&'s so we properly propagate failures between commands in the hook helper functions. Also add a missing mkdir -p arg (found by adding the &&). Reported-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 daysobject-file: avoid ODB transaction when not writing objectsJustin Tobler
In ce1661f9da (odb: add transaction interface, 2025-09-16), existing ODB transaction logic is adapted to create a transaction interface at the ODB layer. The intent here is for the ODB transaction interface to eventually provide an object source agnostic means to manage transactions. An unintended consequence of this change though is that `object-file.c:index_fd()` may enter the ODB transaction path even when no object write is requested. In non-repository contexts, this can result in a NULL dereference and segfault. One such case occurs when running git-diff(1) outside of a repository with "core.bigFileThreshold" forcing the streaming path in `index_fd()`: $ echo foo >foo $ echo bar >bar $ git -c core.bigFileThreshold=1 diff -- foo bar In this scenario, the caller only needs to compute the object ID. Object hashing does not require an ODB, so starting a transaction is both unnecessary and invalid. Fix the bug by avoiding the use of ODB transactions in `index_fd()` when callers are only interested in computing the object hash. Reported-by: Luca Stefani <luca.stefani.ge1@gmail.com> Signed-off-by: Justin Tobler <jltobler@gmail.com> [jc: adjusted to fd13909e (Merge branch 'jt/odb-transaction', 2025-10-02)] Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 daysMerge branch 'th/backfill-auto-detect-sparseness-fix'Junio C Hamano
"git backfill" is capable of auto-detecting a sparsely checked out working tree, which was broken. * th/backfill-auto-detect-sparseness-fix: backfill: auto-detect sparse-checkout from config
7 daysMerge branch 'ps/receive-pack-updateinstead-in-worktree'Junio C Hamano
The check in "receive-pack" to prevent a checked out branch from getting updated via updateInstead mechanism has been corrected. * ps/receive-pack-updateinstead-in-worktree: receive-pack: use worktree HEAD for updateInstead t5516: clean up cloned and new-wt in denyCurrentBranch and worktrees test t5516: test updateInstead with worktree and unborn bare HEAD
7 daysMerge branch 'jt/fast-import-signed-modes'Junio C Hamano
Handling of signed commits and tags in fast-import has been made more configurable. * jt/fast-import-signed-modes: fast-import: add 'abort-if-invalid' mode to '--signed-tags=<mode>' fast-import: add 'sign-if-invalid' mode to '--signed-tags=<mode>' fast-import: add 'strip-if-invalid' mode to '--signed-tags=<mode>' fast-import: add 'abort-if-invalid' mode to '--signed-commits=<mode>' fast-export: check for unsupported signing modes earlier
7 daysMerge branch 'mm/line-log-use-standard-diff-output'Junio C Hamano
The way the "git log -L<range>:<file>" feature is bolted onto the log/diff machinery is being reworked a bit to make the feature compatible with more diff options, like -S/G. * mm/line-log-use-standard-diff-output: doc: note that -L supports patch formatting and pickaxe options t4211: add tests for -L with standard diff options line-log: route -L output through the standard diff pipeline line-log: fix crash when combined with pickaxe options
7 daysMerge branch 'jc/whitespace-incomplete-line'Junio C Hamano
Fix whitespace correction for new-style empty context lines. * jc/whitespace-incomplete-line: apply: fix new-style empty context line triggering incomplete-line check
7 daysMerge branch 'ps/commit-graph-overflow-fix'Junio C Hamano
Fix a regression in writing the commit-graph where commits with dates exceeding 34 bits (beyond year 2514) could cause an underflow and crash Git during the generation data overflow chunk writing. * ps/commit-graph-overflow-fix: commit-graph: fix writing generations with dates exceeding 34 bits
8 daysMerge branch 'th/t6101-unhide-git-failures'Junio C Hamano
Test cleanup. * th/t6101-unhide-git-failures: t6101: avoid suppressing git's exit code
8 daysMerge branch 'za/t2000-modernise'Junio C Hamano
Test cleanup. * za/t2000-modernise: t2000: modernise overall structure
8 daysMerge branch 'tc/replay-down-to-root'Junio C Hamano
git replay now supports replaying down to the root commit. * tc/replay-down-to-root: replay: support replaying down from root commit
8 daysMerge branch 'tb/stdin-packs-excluded-but-open'Junio C Hamano
pack-objects's --stdin-packs=follow mode learns to handle excluded-but-open packs. * tb/stdin-packs-excluded-but-open: repack: mark non-MIDX packs above the split as excluded-open pack-objects: support excluded-open packs with --stdin-packs t7704: demonstrate failure with once-cruft objects above the geometric split pack-objects: refactor `read_packs_list_from_stdin()` to use `strmap` pack-objects: plug leak in `read_stdin_packs()`
8 daysMerge branch 'ps/odb-generic-object-name-handling'Junio C Hamano
Object name handling (disambiguation and abbreviation) has been refactored to be backend-generic, moving logic into the respective object database backends. * ps/odb-generic-object-name-handling: odb: introduce generic `odb_find_abbrev_len()` object-file: move logic to compute packed abbreviation length object-name: move logic to compute loose abbreviation length object-name: simplify computing common prefixes object-name: abbreviate loose object names without `disambiguate_state` object-name: merge `update_candidates()` and `match_prefix()` object-name: backend-generic `get_short_oid()` object-name: backend-generic `repo_collect_ambiguous()` object-name: extract function to parse object ID prefixes object-name: move logic to iterate through packed prefixed objects object-name: move logic to iterate through loose prefixed objects odb: introduce `struct odb_for_each_object_options` oidtree: extend iteration to allow for arbitrary return codes oidtree: modernize the code a bit object-file: fix sparse 'plain integer as NULL pointer' error
9 daysbackfill: auto-detect sparse-checkout from configTrieu Huynh
Commit 85127bcdea ("backfill: assume --sparse when sparse-checkout is enabled") intended for 'git backfill' to consult the repository configuration when the user does not pass '--sparse' or '--no-sparse' on the command line. It added the sentinel check: if (ctx->sparse < 0) ctx->sparse = cfg->apply_sparse_checkout; However, the ctx->sparse field is initialized to 0 instead of -1, so this guard never triggers. Consequently, the repository config (core.sparseCheckout) is never checked, and the command always performs a full backfill even when sparse-checkout is enabled. Fix this by initializing ctx->sparse to -1, ensuring the existing fallback logic correctly reads the repository configuration when no explicit flags are provided. Add a test to verify that 'git backfill' automatically respects sparse-checkout settings when no flags are passed. Signed-off-by: Trieu Huynh <vikingtc4@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
11 daysMerge branch 'ps/dash-buggy-0.5.13-workaround'Junio C Hamano
The way dash 0.5.13 handles non-ASCII contents in here-doc is buggy and breaks our existing tests, which unfortunately have been rewritten to avoid triggering the bug. * ps/dash-buggy-0.5.13-workaround: t9300: work around partial read bug in Dash v0.5.13 t: work around multibyte bug in quoted heredocs with Dash v0.5.13
11 daysMerge branch 'th/t8003-unhide-git-failures'Junio C Hamano
Test clean-up. * th/t8003-unhide-git-failures: t8003: modernise style t8003: avoid suppressing git's exit code
11 daysMerge branch 'sa/replay-revert'Junio C Hamano
"git replay" (experimental) learns, in addition to "pick" and "replay", a new operating mode "revert". * sa/replay-revert: replay: add --revert mode to reverse commit changes sequencer: extract revert message formatting into shared function
11 daysMerge branch 'pw/worktree-reduce-the-repository'Junio C Hamano
Reduce the reference to the_repository in the worktree subsystem. * pw/worktree-reduce-the-repository: worktree: reject NULL worktree in get_worktree_git_dir() worktree add: stop reading ".git/HEAD" worktree: remove "the_repository" from is_current_worktree()
11 daysMerge branch 'ar/config-hook-cleanups'Junio C Hamano
Code clean-up around the recent "hooks defined in config" topic. * ar/config-hook-cleanups: hook: reject unknown hook names in git-hook(1) hook: show disabled hooks in "git hook list" hook: show config scope in git hook list hook: introduce hook_config_cache_entry for per-hook data t1800: add test to verify hook execution ordering hook: make consistent use of friendly-name in docs hook: replace hook_list_clear() -> string_list_clear_func() hook: detect & emit two more bugs hook: rename cb_data_free/alloc -> hook_data_free/alloc hook: fix minor style issues builtin/receive-pack: properly init receive_hook strbuf hook: move unsorted_string_list_remove() to string-list.[ch]
11 daysMerge branch 'ds/backfill-revs'Junio C Hamano
`git backfill` learned to accept revision and pathspec arguments. * ds/backfill-revs: t5620: test backfill's unknown argument handling path-walk: support wildcard pathspecs for blob filtering backfill: work with prefix pathspecs backfill: accept revision arguments t5620: prepare branched repo for revision tests revision: include object-name.h
11 daysMerge branch 'mf/format-patch-commit-list-format'Junio C Hamano
Improve the recently introduced `git format-patch --commit-list-format` (formerly `--cover-letter-format`) option, including a new "modern" preset and better CLI ergonomics. * mf/format-patch-commit-list-format: format-patch: --commit-list-format without prefix format-patch: add preset for --commit-list-format format-patch: wrap generate_commit_list_cover() format.commitListFormat: strip meaning from empty docs/pretty-formats: add %(count) and %(total) format-patch: rename --cover-letter-format option format-patch: refactor generate_commit_list_cover pretty.c: better die message %(count) and %(total)
11 daysMerge branch 'mf/format-patch-cover-letter-format'Junio C Hamano
"git format-patch --cover-letter" learns to use a simpler format instead of the traditional shortlog format to list its commits with a new --cover-letter-format option and format.commitListFormat configuration variable. * mf/format-patch-cover-letter-format: docs: add usage for the cover-letter fmt feature format-patch: add commitListFormat config format-patch: add ability to use alt cover format format-patch: move cover letter summary generation pretty.c: add %(count) and %(total) placeholders
12 dayst9300: work around partial read bug in Dash v0.5.13Patrick Steinhardt
When executing t9300 with Dash v0.5.13.1 we can see that the test hangs completely with the following (condensed) trace: git fast-import + error=1 + read output + cat input + echo checkpoint + echo progress checkpoint + test rogress checkpoint = progress checkpoint + test rogress checkpoint = UNEXPECTED + echo cruft: rogress checkpoint cruft: rogress checkpoint + read output + test = progress checkpoint + test = UNEXPECTED + echo cruft: cruft: + read output Basically, what's happening here is that we spawn git-fast-import(1) and wait for it to output a certain string, "progress checkpoint". Curiously though, what we end up reading is "rogress checkpoint" -- so the first byte of the expected string is missing. Same as in the preceding commit, this seems to be a bug in Dash itself that bisects to c5bf970 (expand: Add multi-byte support to pmatch, 2024-06-02). But other than in the preceding commit, this bug has already been fixed upstream in 079059a (input: Fix heap-buffer-overflow in preadbuffer on long lines, 2026-02-11), which is part of v0.5.13.2. For now though, work around the bug by waiting for the expected output in a different way. There is no good reason why one version should work better than the other, but at least the new version doesn't exhibit the bug. And, if you ask me, it's also slightly easier to read. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
12 dayst: work around multibyte bug in quoted heredocs with Dash v0.5.13Patrick Steinhardt
When executing our test suite with Dash v0.5.13.2 one can observe several test failures that all have the same symptoms: we have a quoted heredoc that contains multibyte characters, but the final data does not match what we actually wanted to write. One such example is in t0300, where we see the diffs like the following: --- expect-stdout 2026-04-01 07:25:45.249919440 +0000 +++ stdout 2026-04-01 07:25:45.254919509 +0000 @@ -1,5 +1,5 @@ protocol=https host=example.com -path=perú.git +path=perú.git username=foo password=bar While seemingly the same, the data that we've written via the heredoc contains some invisible bytes. The expected hex representation of the string is: 7065 72c3 ba2e 6769 74 per...git But what we actually get instead is this string: 7065 7285 02c3 ba02 852e 6769 74 per.......git What's important to note here is that the multibyte character exists in both versions. But in the broken version we see that the bytes are wrapped in a sequence of "85 02" and "02 85". This is the CTLMBCHAR byte sequence of Dash, which it uses internally to quote multibyte sequences. As it turns out, this bug was introduced in c5bf970 (expand: Add multi-byte support to pmatch, 2024-06-02), which adds multibyte support to more contexts of Dash. One of these contexts seems to be in heredocs, and Dash _does_ correctly unquote these multibyte sequences when using an unquoted heredoc. But the bug seems to be that this unquoting does not happen in quoted heredocs, and the bug still exists on the latest "master" branch. For now, work around the bug by using unquoted heredocs instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
13 daysreplay: allow to specify a ref with option --refToon Claes
When option '--onto' is passed to git-replay(1), the command will update refs from the <revision-range> passed to the command. When using option '--advance' or '--revert', the argument of that option is a ref that will be updated. To enable users to specify which ref to update, add option '--ref'. When using option '--ref', the refs described above are left untouched and instead the argument of this option is updated instead. Because this introduces code paths in replay.c that jump to `out` before init_basic_merge_options() is called on `merge_opt`, zero-initialize the struct. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
13 daysread-cache: disable renames in add_files_to_cacheNick Golden
add_files_to_cache() refreshes the index from worktree changes and does not need rename detection. When unmerged entries and a deleted stage-0 path are present together, rename detection can pair them and rewrite an unmerged diff pair to point at the deleted path. That later makes "git commit -a" and "git add -u" try to stat the deleted path and die with "unable to stat". Disable rename detection in this callback-driven staging path and add a regression test covering the crash. Signed-off-by: Nick Golden <blindmansion@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
13 dayst7004: replace wc -l with modern test helpersSiddharth Shrimali
Pipelines of the form "test $(git tag | wc -l) -eq 0" suppress git's exit code. This means a crash or unexpected failure from git tag would go undetected. Additionally, the use of $(...) creates a subshell for each check, which adds unnecessary overhead. Replace these patterns with test_must_be_empty and test_line_count. These helpers check the output of git directly from a file, ensuring git's exit code is captured properly via the preceding "&&" chain. They also provide better diagnostics on failure by printing the contents of the file when a check does not pass. Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
14 daysMerge branch 'kj/refspec-parsing-outside-repository'Junio C Hamano
"git ls-remote '+refs/tags/*:refs/tags/*' https://..." run outside a repository would dereference a NULL while trying to see if the given refspec is a single-object refspec, which has been corrected. * kj/refspec-parsing-outside-repository: refspec: fix typo in comment remote-curl: fall back to default hash outside repo
14 daysMerge branch 'jk/t0061-bat-test-update'Junio C Hamano
A test to run a .bat file with whitespaces in the name with arguments with whitespaces in them was flaky in that sometimes it got killed before it produced expected side effects, which has been rewritten to make it more robust. * jk/t0061-bat-test-update: t0061: simplify .bat test
14 daysMerge branch 'mk/repo-help-strings'Junio C Hamano
"git repo info -h" and "git repo structure -h" limit their help output to the part that is specific to the subcommand. * mk/repo-help-strings: repo: show subcommand-specific help text repo: factor repo usage strings into shared macros
14 daysMerge branch 'bk/t5315-test-path-is-helpers'Junio C Hamano
Test clean-up. * bk/t5315-test-path-is-helpers: t5315: use test_path_is_file for loose-object check
14 daysMerge branch 'jk/diff-highlight-more'Junio C Hamano
Various updates to contrib/diff-highlight, including documentation updates, test improvements, and color configuration handling. * jk/diff-highlight-more: diff-highlight: fetch all config with one process diff-highlight: allow module callers to pass in color config diff-highlight: test color config diff-highlight: use test_decode_color in tests t: add matching negative attributes to test_decode_color diff-highlight: check diff-highlight exit status in tests diff-highlight: drop perl version dependency back to 5.8 diff-highlight: mention build instructions
14 daysMerge branch 'vp/http-rate-limit-retries'Junio C Hamano
The HTTP transport learned to react to "429 Too Many Requests". * vp/http-rate-limit-retries: http: add support for HTTP 429 rate limit retries strbuf_attach: fix call sites to pass correct alloc strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()
2026-03-30Merge branch 'ai/t2107-test-path-is-helpers'Junio C Hamano
Test cleanup. * ai/t2107-test-path-is-helpers: t2107: modernize path existence check
2026-03-30Merge branch 'jw/t2203-status-pipe-fix'Junio C Hamano
Test clean-up. * jw/t2203-status-pipe-fix: t2203: avoid suppressing git status exit code
2026-03-30Merge branch 'jw/apply-corrupt-location'Junio C Hamano
"git apply" now reports the name of the input file along with the line number when it encounters a corrupt patch, and correctly resets the line counter when processing multiple patch files. * jw/apply-corrupt-location: apply: report input location in binary and garbage patch errors apply: report input location in header parsing errors apply: report the location of corrupt patches
2026-03-30receive-pack: use worktree HEAD for updateInsteadPablo Sabater
When a bare repo has linked worktrees, and its HEAD points to an unborn branch, pushing to a wt branch with updateInstead fails and rejects the push, even if the wt is clean. This happens because HEAD is checked only for the bare repo context, instead of the wt. Remove head_has_history and check for worktree->head_oid which does have the correct HEAD of the wt. Update the test added by Runxi's patch to expect success. Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-30t5516: clean up cloned and new-wt in denyCurrentBranch and worktrees testPablo Sabater
The 'denyCurrentBranch and worktrees' test creates a 'cloned' and a 'new-wt' but it doesn't clean them after the test. This makes other tests that use the same name after this one to fail. Add test_when_finished to clean them at the end. Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-30t5516: test updateInstead with worktree and unborn bare HEADRunxi Yu
This is a regression test which should presently fail, to demonstrate the behavior I encountered that looks like a bug. When a bare repository has a worktree checked out on a separate branch, receive.denyCurrentBranch=updateInstead should allow a push to that branch and update the linked worktree, as long as the linked worktree is clean. But, if the bare repository's own HEAD is repointed to an unborn branch, the push is rejected with "Working directory has staged changes", even though the linked worktree itself is clean. This test is essentially a minimal working example of what I encountered while actually using Git; it might not be the optimal way to demonstrate the underlying bug. I suspect builtin/receive-pack.c is using the bare repository's HEAD even when comparing it to the worktree's index. Signed-off-by: Runxi Yu <me@runxiyu.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-28t6101: avoid suppressing git's exit codeTrieu Huynh
Update t6101-rev-parse-parents.sh to redirect git-rev-parse output to a temporary file instead of piping it directly to not hide the exit code of git commands behind pipes, as a crash in git might go unnoticed. Signed-off-by: Trieu Huynh <vikingtc4@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-28t8003: modernise styleTrieu Huynh
Remove the blank lines at both ends of each test_expect_success body to match the modern style used elsewhere in the test suite. Signed-off-by: Trieu Huynh <vikingtc4@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-28t8003: avoid suppressing git's exit codeTrieu Huynh
Update t8003-blame-corner-cases.sh to redirect git-blame output to a temporary file instead of piping it directly to not hide the exit code of git commands behind pipes, as a crash in git might go unnoticed. Signed-off-by: Trieu Huynh <vikingtc4@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-28t2000: modernise overall structureZakariyah Ali
This test script that dates back to 2005 certainly shows its age and both its style and the way the tests are laid out do not match the modern standard. * Executables that prepare the data used to test the command should be inside the test_expect_success block in modern tests. * In modern tests, running a command that is being tested, making sure it succeeds, and inspecting other side effects that are expected, are all done in a single test_expect_success block. * A test_expect_success block in modern tests are laid out as test_expect_success 'title of the test' ' body of the test && ... body of the test ' not as test_expect_success \ 'title of the test' \ 'body of the test && ... body of the test' which is in a prehistoric style. * In modern tests, each &&-chained statement in the body of the test_expect_success block are indented with a horizontal tab, unlike prehistoric style that used 4-space indent. Signed-off-by: Zakariyah Ali <zakariyahali100@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-27repack: mark non-MIDX packs above the split as excluded-openTaylor Blau
In 5ee86c273bf (repack: exclude cruft pack(s) from the MIDX where possible, 2025-06-23), geometric repacking learned to exclude cruft packs from the MIDX when 'repack.midxMustContainCruft' is set to 'false'. This works because packs generated with '--stdin-packs=follow' rescue any once-unreachable objects that later become reachable, making the resulting packs closed under reachability without needing the cruft pack in the MIDX. However, packs above the geometric split that were not part of the previous MIDX may not have full object closure. When such packs are marked as excluded-closed ('^'), pack-objects treats them as a reachability boundary and does not traverse through them during the follow pass, potentially leaving the resulting pack without full closure. Fix this by marking packs above the geometric split that were not in the previous MIDX as excluded-open ('!') instead of excluded-closed ('^'). This causes pack-objects to walk through their commits during the follow pass, rescuing any reachable objects not present in the closed-excluded packs. Note that MIDXs which were generated prior to this change and are unlucky enough to not be closed under reachability may still exhibit this bug, as we treat all MIDX'd packs as closed. That is true in an overwhelming number of cases, since in order to have a non-closed MIDX you would have to: - Generate a pack via an earlier geometric repack that is not closed under reachability. - Store that pack in the MIDX. - Avoid picking any commits to receive reachability bitmaps which happen to reach objects from which the missing objects are reachable. In the extremely rare chance that all of the above should happen, an all-into-one repack will resolve the issue. Unfortunately, there is no perfect way to determine whether a MIDX'd pack is closed outside of ensuring that there is a '1' bit in at least one bitmap for every bit position corresponding to objects in that pack. While this is possible to do, this approach would treat MIDX'd packs as open in cases where there is at least one object that is not reachable from the subset of commits selected for bitmapping. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-27pack-objects: support excluded-open packs with --stdin-packsTaylor Blau
In cd846bacc7d (pack-objects: introduce '--stdin-packs=follow', 2025-06-23), pack-objects learned to traverse through commits in included packs when using '--stdin-packs=follow', rescuing reachable objects from unlisted packs into the output. When we encounter a commit in an excluded pack during this rescuing phase we will traverse through its parents. But because we set `revs.no_kept_objects = 1`, commit simplification will prevent us from showing it via `get_revision()`. (In practice, `--stdin-packs=follow` walks commits down to the roots, but only opens up trees for ones that do not appear in an excluded pack.) But there are certain cases where we *do* need to see the parents of an object in an excluded pack. Namely, if an object is rescue-able, but only reachable from object(s) which appear in excluded packs, then commit simplification will exclude those commits from the object traversal, and we will never see a copy of that object, and thus not rescue it. This is what causes the failure in the previous commit during repacking. When performing a geometric repack, packs above the geometric split that weren't part of the previous MIDX (e.g., packs pushed directly into `$GIT_DIR/objects/pack`) may not have full object closure. When those packs are listed as excluded via the '^' marker, the reachability traversal encounters the sequence described above, and may miss objects which we expect to rescue with `--stdin-packs=follow`. Introduce a new "excluded-open" pack prefix, '!'. Like '^'-prefixed packs, objects from '!'-prefixed packs are excluded from the resulting pack. But unlike '^', commits in '!'-prefixed packs *are* used as starting points for the follow traversal, and the traversal does not treat them as a closure boundary. In order to distinguish excluded-closed from excluded-open packs during the traversal, introduce a new `pack_keep_in_core_open` bit on `struct packed_git`, along with a corresponding `KEPT_PACK_IN_CORE_OPEN` flag for the kept-pack cache. In `add_object_entry_from_pack()`, move the `want_object_in_pack()` check to *after* `add_pending_oid()`. This is necessary so that commits from excluded-open packs are added as traversal tips even though their objects won't appear in the output. As a consequence, the caller `for_each_object_in_pack()` will always provide a non-NULL 'p', hence we are able to drop the "if (p)" conditional. The `include_check` and `include_check_obj` callbacks on `rev_info` are used to halt the walk at closed-excluded packs, since objects behind a '^' boundary are guaranteed to have closure and need not be rescued. The following commit will make use of this new functionality within the repack layer to resolve the test failure demonstrated in the previous commit. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-27t7704: demonstrate failure with once-cruft objects above the geometric splitTaylor Blau
Add a test demonstrating a case where geometric repacking fails to produce a pack with full object closure, thus making it impossible to write a reachability bitmap. Mark the test with 'test_expect_failure' for now. The subsequent commit will explain the precise failure mode, and implement a fix. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>