summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-01-16Merge branch 'ac/t1420-use-more-direct-check'Junio C Hamano
Test update. * ac/t1420-use-more-direct-check: t1420: modernize the lost-found test
2026-01-16Merge branch 'jk/cat-file-avoid-bitmap-when-unneeded'Junio C Hamano
Fix for a performance regression in "git cat-file". * jk/cat-file-avoid-bitmap-when-unneeded: cat-file: only use bitmaps when filtering
2026-01-16Merge branch 'jk/t-perf-fixes'Junio C Hamano
Perf-test fixes. * jk/t-perf-fixes: t/perf/run: preserve GIT_PERF_* from environment t/perf/perf-lib: fix assignment of TEST_OUTPUT_DIRECTORY
2026-01-15cocci: remove obsolete the_repository rulesRené Scharfe
035c7de9e9e (cocci: apply the "revision.h" part of "the_repository.pending", 2023-03-28) removed the last of the repo-less functions and macros mentioned in the_repository.cocci at the time. No stragglers appeared since then. Remove the applied rules now that they have outlived their usefulness. Also add a reminder to eventually remove the just added rules for tree.h. Suggested-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-15Revert "Merge branch 'ar/run-command-hook'"Junio C Hamano
This reverts commit f406b8955295d01089ba2baf35eceadff2d11cae, reversing changes made to 1627809eeff75e6ec936fc609e7be46d5eb2fa9e. It seems to have caused a few regressions, two of the three known ones we have proposed solutions for. Let's give ourselves a bit more room to maneuver during the pre-release freeze period and restart once the 2.53 ships.
2026-01-15Git 2.53-rc0v2.53.0-rc0Junio C Hamano
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-15Merge branch 'ps/clar-integers'Junio C Hamano
Import newer version of "clar", unit testing framework. * ps/clar-integers: gitattributes: disable blank-at-eof errors for clar test expectations t/unit-tests: demonstrate use of integer comparison assertions t/unit-tests: update clar to 39f11fe
2026-01-15Merge branch 'kh/replay-invalid-onto-advance'Junio C Hamano
Improve the error message when a bad argument is given to the `--onto` option of "git replay". Test coverage of "git replay" has been improved. * kh/replay-invalid-onto-advance: t3650: add more regression tests for failure conditions replay: die if we cannot parse object replay: improve code comment and die message replay: die descriptively when invalid commit-ish is given replay: find *onto only after testing for ref name replay: remove dead code and rearrange
2026-01-15Merge branch 'ps/odb-misc-fixes'Junio C Hamano
Miscellaneous fixes on object database layer. * ps/odb-misc-fixes: odb: properly close sources before freeing them builtin/gc: fix condition for whether to write commit graphs
2026-01-15Merge branch 'pt/t7800-difftool-test-racefix'Junio C Hamano
Test fixup. * pt/t7800-difftool-test-racefix: t7800: fix racy "difftool --dir-diff syncs worktree" test
2026-01-15Documentation/config: fix replacement for --get-urlmatchPushkar Singh
The documentation claims that --get-urlmatch is replaced by git config get --all --show-names --url=<URL> <name> However, --url cannot be combined with --all, and this command fails in practice. Update the replacement to use only --url, which matches the actual behavior of --get-urlmatch. Signed-off-by: Pushkar Singh <pushkarkumarsingh1970@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-14builtin/repack: handle promisor packs with geometric repackingPatrick Steinhardt
When performing a fetch with an object filter, we mark the resulting packfile as a promisor pack. An object part of such a pack may miss any of its referenced objects, and Git knows to handle this case by fetching any such missing objects from the promisor remote. The "promisor" property needs to be retained going forward. So every time we pack a promisor object, the resulting pack must be marked as a promisor pack. git-repack(1) does this already: when a repository has a promisor remote, it knows to pass "--exclude-promisor-objects" to the git-pack-objects(1) child process. Promisor packs are written separately when doing an all-into-one repack via `repack_promisor_objects()`. But we don't support promisor objects when doing a geometric repack yet. Promisor packs do not get any special treatment there, as we simply merge promisor and non-promisor packs. The resulting pack is not even marked as a promisor pack, which essentially corrupts the repository. This corruption couldn't happen in the real world though: we pass both "--exclude-promisor-objects" and "--stdin-packs" to git-pack-objects(1) if a repository has a promisor remote, but as those options are mutually exclusive we always end up dying. And while we made those flags compatible with one another in a preceding commit, we still end up dying in case git-pack-objects(1) is asked to repack a promisor pack. There's multiple ways to fix this: - We can exclude promisor packs from the geometric progression altogether. This would have the consequence that we never repack promisor packs at all. But in a partial clone it is quite likely that the user generates a bunch of promisor packs over time, as every backfill fetch would create another one. So this doesn't really feel like a sensible option. - We can adapt git-pack-objects(1) to support repacking promisor packs and include them in the normal geometric progression. But this would mean that the set of promisor objects expands over time as the packs are merged with normal packs. - We can use a separate geometric progression to repack promisor packs. The first two options both have significant downsides, so they aren't really feasible. But the third option fixes both of these downsides: we make sure that promisor packs get merged, and at the same time we never expand the set of promisor objects beyond the set of objects that are already marked as promisor objects. Implement this strategy so that geometric repacking works in partial clones. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-14repack-promisor: extract function to remove redundant packsPatrick Steinhardt
We're about to add a second caller that wants to remove redundant packs after a geometric repack. Split out the function which does this to prepare for that. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-14repack-promisor: extract function to finalize repackingPatrick Steinhardt
We're about to add a second caller that wants to finalize repacking of promisor objects. Split out the function which does this to prepare for that. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-14repack-geometry: extract function to compute repacking splitPatrick Steinhardt
We're about to add a second caller that wants to compute the repacking split for a set of packfiles. Split out the function that computes this split to prepare for that. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-14builtin/pack-objects: exclude promisor objects with "--stdin-packs"Patrick Steinhardt
It is currently not possible to combine "--exclude-promisor-objects" with "--stdin-packs" because both flags want to set up a revision walk to enumerate the objects to pack. In a subsequent commit though we want to extend geometric repacks to support promisor objects, and for that we need to handle the combination of both flags. There are two cases we have to think about here: - "--stdin-packs" asks us to pack exactly the objects part of the specified packfiles. It is somewhat questionable what to do in the case where the user asks us to exclude promisor objects, but at the same time explicitly passes a promisor pack to us. For now, we simply abort the request as it is self-contradicting. As we have also been dying before this commit there is no regression here. - "--stdin-packs=follow" does the same as the first flag, but it also asks us to include all objects transitively reachable from any object in the packs we are about to repack. This is done by doing the revision walk mentioned further up. Luckily, fixing this case is trivial: we only need to modify the revision walk to also set the `exclude_promisor_objects` field. Note that we do not support the "--exclude-promisor-objects-best-effort" flag for now as we don't need it to support geometric repacking with promisor objects. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-13midx-write.c: assume checksum-invalid MIDXs require an updateTaylor Blau
In 6ce9d558ced (midx-write: skip rewriting MIDX with `--stdin-packs` unless needed, 2025-12-10), the MIDX machinery learned how to optimize out unnecessary writes with "--stdin-packs". In order to do this, it compares the contents of the in-progress write against a MIDX loaded directly from the object store. We load a separate MIDX (as opposed to checking our update relative to "ctx.m") because the MIDX code does not reuse an existing MIDX with --stdin-packs, and always leaves "ctx.m" as NULL. See commit 0c5a62f14bc (midx-write.c: do not read existing MIDX with `packs_to_include`, 2024-06-11) for details on why. If "ctx.m" is non-NULL, however, it is guaranteed to be checksum-valid, since we only assign "ctx.m" when "midx_checksum_valid()" returns true. Since the same guard does not exist for the MIDX we pass to "midx_needs_update()", we may ignore on-disk corruption when determining whether or not we can optimize out the write. Add a similar guard within "midx_needs_update()" to prevent such an issue. A more robust fix would involve revising 0c5a62f14bc and teaching the MIDX generation code how to reuse an existing MIDX even when invoked with "--stdin-packs", such that we could avoid side-loading the MIDX directly from the object store in order to call "midx_needs_update()". For now, pursue the minimal fix. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-13t/t5319-multi-pack-index.sh: drop early 'test_done'Taylor Blau
In 6ce9d558ced (midx-write: skip rewriting MIDX with `--stdin-packs` unless needed, 2025-12-10), an extra 'test_done' was added, causing the test script to finish before having run all of its tests. Dropping this extraneous 'test_done' exposes a bug from commit 6ce9d558ced that causes a subsequent test to fail. Mark that test with a 'test_expect_failure' for now, and the subsequent commit will explain and fix the bug. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-13Merge branch 'ps/repack-avoid-noop-midx-rewrite' into ↵Junio C Hamano
tb/midx-write-corrupt-checksum-fix * ps/repack-avoid-noop-midx-rewrite: midx-write: skip rewriting MIDX with `--stdin-packs` unless needed midx-write: extract function to test whether MIDX needs updating midx: fix `BUG()` when getting preferred pack without a reverse index
2026-01-12utf8.c: enable workaround for iconv under macOS 14/15Torsten Bögershausen
The previous commit introduced a workaround in utf8.c to deal with broken iconv implementations. It is enabled when a MacOS version is used that has a buggy iconv library and there is no external library provided (and linked against) from neither MacPorts nor Homebrew nor Fink. For Homebrew, MacPorts and Fink we check if libiconv exist. Introduce 2 new macros: HAS_GOOD_LIBICONV and NEEDS_GOOD_LIBICONV. For Homebrew HAS_GOOD_LIBICONV is set when the libiconv directory exist. MacPorts can be installed with or without libiconv, so check if libiconv.dylib exists (which is a softlink) Fink compiles and installs libiconv by default. Note that a fresh installation of Fink now defaults to /opt/sw. Older versions used /sw as default, so leave the check and setting of BASIC_CFLAGS and BASIC_LDFLAGS as is. For the new default check for the existance of /opt/sw as well. Add a check for /opt/sw/lib/libiconv.dylib which sets HAS_GOOD_LIBICONV Signed-off-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12utf8.c: prepare workaround for iconv under macOS 14/15Torsten Bögershausen
MacOS14 (Sonoma) has started to ship an iconv library with bugs. The same bugs exists even in MacOS 15 (Sequoia) A bug report running the Git test suite says: three tests of t3900 fail on macOS 26.1 for me: not ok 17 - ISO-2022-JP should be shown in UTF-8 now not ok 25 - ISO-2022-JP should be shown in UTF-8 now not ok 38 - commit --fixup into ISO-2022-JP from UTF-8 Here's the verbose output of the first one: ================= expecting success of 3900.17 'ISO-2022-JP should be shown in UTF-8 now': compare_with ISO-2022-JP "$TEST_DIRECTORY"/t3900/2-UTF-8.txt --- /Users/x/src/git/t/t3900/2-UTF-8.txt 2024-10-01 19:43:24.605230684 +0000 +++ current 2025-12-08 21:52:45.786161909 +0000 @@ -1,5 +1,5 @@ はれひほふ しているのが、いるので。 -濱浜ほれぷりぽれまびぐりろへ。 +濱浜ほれぷりぽれまび$0$j$m$X!# not ok 17 - ISO-2022-JP should be shown in UTF-8 now 1..17 ================= compare_with runs git show to display a commit message, which in this case here was encoded using ISO-2022-JP and is supposed to be reencoded to UTF-8, but git show only does that half-way -- the "$0$j$m$X!#" part is from the original ISO-2022-JP representation. That botched conversion is done by utf8.c::reencode_string_iconv(). It calls iconv(3) to do the actual work, initially with an output buffer of the same size as the input. If the output needs more space the function enlarges the buffer and calls iconv(3) again. iconv(3) won't tell us how much space it needs, but it will report what part it already managed to convert, so we can increase the buffer and continue from there. ISO-2022-JP has escape codes for switching between character sets, so it's a stateful encoding. I guess the iconv(3) on my machine forgets the state at the end of part one and then messes up part two. [end of citation] Working around the buggy iconv shipped with the OS can be done in two ways: a) Link Git against a different version of iconv b) Improve the handling when iconv needs a larger output buffer a) is already done by default when either Fink [1] or MacPorts [2] or Homebrew [3] is installed. b) is implemented here, in case that no fixed iconv is available: When the output buffer is too short, increase it (as before) and start from scratch (this is new). This workound needs to be enabled with '#define ICONV_RESTART_RESET' and a makefile knob will be added in the next commit Suggested-by: René Scharfe <l.s.r@web.de> Signed-off-by: Torsten Bögershausen <tboegi@web.de> [1] https://www.finkproject.org/ [2] https://www.macports.org/ [3] https://brew.sh/ Signed-off-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12builtin/fsck: drop `fsck_head_link()`Patrick Steinhardt
The function `fsck_head_link()` was historically used to perform a couple of consistency checks for refs. (Almost) all of these checks have now been moved into the refs subsystem. There's only a single check remaining that verifies whether `refs_resolve_ref_unsafe()` returns a `NULL` pointer. This may happen in a couple of cases: - When `refs_is_safe()` declares the ref to be unsafe. We already have checks for this as we verify refnames with `check_refname_format()`. - When the ref doesn't exist. A repository without "HEAD" is completely broken though, and we would notice this error ahead of time already. - In case the caller passes `RESOLVE_REF_READING` and the ref is a symref that doesn't resolve. We don't pass this flag though. As such, this check doesn't cover anything anymore that isn't already covered by `refs_fsck()`. Drop it, which also allows us to inline the call to `refs_resolve_ref_unsafe()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12builtin/fsck: move generic HEAD check into `refs_fsck()`Patrick Steinhardt
Move the check that detects "HEAD" refs that do not point at a branch into `refs_fsck()`. This follows the same motivation as the preceding commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12builtin/fsck: move generic object ID checks into `refs_fsck()`Patrick Steinhardt
While most of the logic that verifies the consistency of refs is driven by `refs_fsck()`, we still have a small handful of checks in `fsck_head_link()`. These checks don't use the git-fsck(1) reporting infrastructure, and as such it's impossible to for example disable some of those checks. One such check detects refs that point to the all-zeroes object ID. Extract this check into the generic `refs_fsck_ref()` function that is used by both the "files" and "reftable" backends. Note that this will cause us to not return an error code from `fsck_head_link()` anymore in case this error was detected. This is fine though: the only caller of this function does not check the error code anyway. To demonstrate this, adapt the function to drop its return value altogether. The function will be removed in a subsequent commit anyway. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/reftable: introduce generic checks for refsPatrick Steinhardt
In a preceding commit we have extracted generic checks for both direct and symbolic refs that apply for all backends. Wire up those checks for the "reftable" backend. Note that this is done by iterating through all refs manually with the low-level reftable ref iterator. We explicitly don't want to use the higher-level iterator that is exposed to users of the reftable backend as that iterator may swallow for example broken refs. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/reftable: fix consistency checks with worktreesPatrick Steinhardt
The ref consistency checks are driven via `cmd_refs_verify()`. That function loops through all worktrees (including the main worktree) and then checks the ref store for each of them individually. It follows that the backend is expected to only verify refs that belong to the specified worktree. While the "files" backend handles this correctly, the "reftable" backend doesn't. In fact, it completely ignores the passed worktree and instead verifies refs of _all_ worktrees. The consequence is that we'll end up every ref store N times, where N is the number of worktrees. Or rather, that would be the case if we actually iterated through the worktree reftable stacks correctly. But we use `strmap_for_each_entry()` to iterate through the stacks, but the map is in fact not even properly populated. So instead of checking stacks N^2 times, we actually only end up checking the reftable stack of the main worktree. Fix this bug by only verifying the stack of the passed-in worktree and constructing the backends via `backend_for_worktree()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/reftable: extract function to retrieve backend for worktreePatrick Steinhardt
Pull out the logic to retrieve a backend for a given worktree. This function will be used in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/reftable: adapt includes to become consistentPatrick Steinhardt
Adapt the includes to be sorted and to use include paths that are relative to the "refs/" directory. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: introduce function to perform normal ref checksPatrick Steinhardt
In a subsequent commit we'll introduce new generic checks for direct refs. These checks will be independent of the actual backend. Introduce a new function `refs_fsck_ref()` that will be used for this purpose. At the current point in time it's still empty, but it will get populated in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: extract generic symref target checksPatrick Steinhardt
The consistency checks for the "files" backend contain a couple of verifications for symrefs that verify generic properties of the target reference. These properties need to hold for every backend, no matter whether it's using the "files" or "reftable" backend. Reimplementing these checks for every single backend doesn't really make sense. Extract it into a generic `refs_fsck_symref()` function that can be used by other backends, as well. The "reftable" backend will be wired up in a subsequent commit. While at it, improve the consistency checks so that we don't complain about refs pointing to a non-ref target in case the target refname format does not verify. Otherwise it's very likely that we'll generate both error messages, which feels somewhat redundant in this case. Note that the function has a couple of `UNUSED` parameters. These will become referenced in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12fsck: drop unused fields from `struct fsck_ref_report`Patrick Steinhardt
The `struct fsck_ref_report` has a couple fields that are intended to improve the error reporting for broken ref reports by showing which object ID or target reference the ref points to. These fields are never set though and are thus essentially unused. Remove them. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: perform consistency checks for root refsPatrick Steinhardt
While the "files" backend already knows to perform consistency checks for the "refs/" hierarchy, it doesn't verify any of its root refs. Plug this omission. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: improve error handling when verifying symrefsPatrick Steinhardt
The error handling when verifying symbolic refs is a bit on the wild side: - `fsck_report_ref()` can be told to ignore specific errors. If an error has been ignored and a previous check raised an unignored error, then assigning `ret = fsck_report_ref()` will cause us to swallow the previous error. - When the target reference is not valid we bail out early without checking for other errors. Fix both of these issues by consistently or'ing the return value and not bailing out early. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: extract function to check single refPatrick Steinhardt
When checking the consistency of references we create a directory iterator and then verify each single reference in a loop. The logic to perform the actual checks is embedded into that loop, which makes it hard to reuse. But In a subsequent commit we're about to introduce a second path that wants to verify references. Prepare for this by extracting the logic to check a single reference into a standalone function. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: remove useless indirectionPatrick Steinhardt
The function `files_fsck_refs()` only has a single callsite and forwards all of its arguments as-is, so it's basically a useless indirection. Inline the function call. While at it, also remove the bitwise or that we have for return values. We don't really want to or them at all, but rather just want to return an error in case either of the functions has failed. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: remove `refs_check_dir` parameterPatrick Steinhardt
The parameter `refs_check_dir` determines which directory we want to check references for. But as we always want to check the complete refs hierarchy, this parameter is always set to "refs". Drop the parameter and hardcode it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: move fsck functions into global scopePatrick Steinhardt
When performing consistency checks we pass the functions that perform the verification down the calling stack. This is somewhat unnecessary though, as the set of functions doesn't ever change. Simplify the code by moving the array into global scope and remove the parameter. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12refs/files: simplify iterating through root refsPatrick Steinhardt
When iterating through root refs we first need to determine the directory in which the refs live. This is done by retrieving the root of the loose refs via `refs->loose->root->name`, and putting it through `files_ref_path()` to derive the final path. This is somewhat redundant though: the root name of the loose files cache is always going to be the empty string. As such, we always end up passing that empty string to `files_ref_path()` as the ref hierarchy we want to start. And this actually makes sense: `files_ref_path()` already computes the location of the root directory, so of course we need to pass the empty string for the ref hierarchy itself. So going via the loose ref cache to figure out that the root of a ref hierarchy is empty is only causing confusion. But next to the added confusion, it can also lead to a segfault. The loose ref cache is populated lazily, so it may not always be set. It seems to be sheer luck that this is a condition we do not currently hit. The right thing to do would be to call `get_loose_ref_cache()`, which knows to populate the cache if required. Simplify the code and fix the potential segfault by simply removing the indirection via the loose ref cache completely. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12packfile: drop repository parameter from `packed_object_info()`Patrick Steinhardt
The function `packed_object_info()` takes a packfile and offset and returns the object info for the corresponding object. Despite these two parameters though it also takes a repository pointer. This is redundant information though, as `struct packed_git` already has a repository pointer that is always populated. Drop the redundant parameter. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12packfile: skip unpacking object header for disk size requestsPatrick Steinhardt
While most of the object info requests for a packed object require us to unpack its headers, reading its disk size doesn't. We still unpack the object header in that case though, which is unnecessary work. Skip reading the header if only the disk size is requested. This leads to a small speedup when reading disk size, only. The following benchmark was done in the Git repository: Benchmark 1: ./git rev-list --disk-usage HEAD (rev = HEAD~) Time (mean ± σ): 105.2 ms ± 0.6 ms [User: 91.4 ms, System: 13.3 ms] Range (min … max): 103.7 ms … 106.0 ms 27 runs Benchmark 2: ./git rev-list --disk-usage HEAD (rev = HEAD) Time (mean ± σ): 96.7 ms ± 0.4 ms [User: 86.2 ms, System: 10.0 ms] Range (min … max): 96.2 ms … 98.1 ms 30 runs Summary ./git rev-list --disk-usage HEAD (rev = HEAD) ran 1.09 ± 0.01 times faster than ./git rev-list --disk-usage HEAD (rev = HEAD~) Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12packfile: disentangle return value of `packed_object_info()`Patrick Steinhardt
The `packed_object_info()` function returns the type of the packed object. While we use an `enum object_type` to store the return value, this type is not to be confused with the actual object type. It _may_ contain the object type, but it may just as well encode that the given packed object is stored as a delta. We have removed the only caller that relied on this returned object type in the preceding commit, so let's simplify semantics and return either 0 on success or a negative error code otherwise. This unblocks a small optimization where we can skip reading the object type altogether. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12packfile: always populate pack-specific info when reading object infoPatrick Steinhardt
When reading object information via `packed_object_info()` we may not populate the object info's packfile-specific fields. This leads to inconsistent object info depending on whether the info was populated via `packfile_store_read_object_info()` or `packed_object_info()`. Fix this inconsistency so that we can always assume the pack info to be populated when reading object info from a pack. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12packfile: extend `is_delta` field to allow for "unknown" statePatrick Steinhardt
The `struct object_info::u::packed::is_delta` field determines whether or not a specific object is stored as a delta. It only stores whether or not the object is stored as delta, so it is treated as a boolean value. This boolean is insufficient though: when reading a packed object via `packfile_store_read_object_info()` we know to skip parsing the actual object when the user didn't request any object-specific data. In that case we won't read the object itself, but will only look up its position in the packfile. Consequently, we do not know whether it is a delta or not. This isn't really an issue right now, as the check for an empty request is broken. But a subsequent commit will fix it, and once we do we will have the need to also represent an "unknown" delta state. Prepare for this change by introducing a new enum that encodes the object type. We don't use the "unknown" state just yet, but will start to do so in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12packfile: always declare object info to be OI_PACKEDPatrick Steinhardt
When reading object info via a packfile we yield one of two types: - The object can either be OI_PACKED, which is what a caller would typically expect. - Or it can be OI_DBCACHED if it is stored in the delta base cache. The latter really is an implementation detail though, and callers typically don't care at all about the difference. Furthermore, the information whether or not it is part of the delta base cache can already be derived via the `is_delta` field, so the fact that we discern between OI_PACKED and OI_DBCACHED only further complicates the interface. There aren't all that many callers that care about the `whence` field in the first place. In fact, there's only three: - `packfile_store_read_object_info()` checks for `whence == OI_PACKED` and then populates the packfile information of the object info structure. We now start to do this also for deltified objects, which gives its callers strictly more information. - `repack_local_links()` wants to determine whether the object is part of a promisor pack and checks for `whence == OI_PACKED`. If so, it verifies that the packfile is a promisor pack. It's arguably wrong to declare that an object is not part of a promisor pack only because it is stored in the delta base cache. - `is_not_in_promisor_pack_obj()` does the same, but checks that a specific object is _not_ part of a promisor pack. The same reasoning as above applies. Drop the OI_DBCACHED enum completely. None of the callers seem to care about the distinction. Note that this also fixes a segfault introduced in 8c1b84bc97 (streaming: move logic to read packed objects streams into backend, 2025-11-23), which refactors how we stream packed objects. The intent is to only read packed objects in case they are stored non-deltified as we'd otherwise have to deflate them first. But the check for whether or not the object is stored as a delta was unconditionally done via `oi.u.packed.is_delta`, which is only valid in case `oi.whence` is `OI_PACKED`. But under some circumstances we got `OI_DBCACHED` here, which means that none of the `oi.u.packed` fields were initialized at all. Consequently, we assumed the object was not stored as a delta, and then try to read the object from `oi.u.packed.pack`, which is a `NULL` pointer and thus causes a segfault. Add a test case for this issue so that this cannot regress in the future anymore. Reported-by: Matt Smiley <msmiley@gitlab.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12object-file: always set OI_LOOSE when reading object infoPatrick Steinhardt
There are some early returns in `odb_source_loose_read_object_info()` in cases where we don't have to open the loose object. These return paths do not set `struct object_info::whence` to `OI_LOOSE` though, so it becomes impossible for the caller to tell the format of such an object. The root cause of this really is that we have so many different return paths in the function. As a consequence, it's harder than necessary to make sure that all successful exit paths sot up the `whence` field as expected. Address this by refactoring the function to have a single exit path. Like this, we can trivially set up the `whence` field when we exit successfully from the function. Note that we also: - Rename `status` to `ret` to match our usual coding style, but also to show that the old `status` variable is now always getting the expected value. Furthermore, the value is not initialized anymore, which has the consequence that most compilers will warn for exit paths where we forgot to set it. - Move the setup of scratch pointers closer to `parse_loose_header()` to show where it's needed. - Guard a couple of variables on cleanup so that they only get released in case they have been set up. - Reset `oi->delta_base_oid` towards the end of the function, together with all the other object info pointers. Overall, all these changes result in a diff that is somewhat hard to read. But the end result is significantly easier to read and reason about, so I'd argue this one-time churn is worth it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12The 17th batchJunio C Hamano
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-12Merge branch 'js/mailmap-karsten-blees'Junio C Hamano
Mailmap update for Karsten * js/mailmap-karsten-blees: .mailmap: replace Karsten Blees' default address
2026-01-12Merge branch 'ps/t1300-2021-use-test-path-is-helpers'Junio C Hamano
Test updates. * ps/t1300-2021-use-test-path-is-helpers: t1300: use test helpers instead of `test` command
2026-01-12Merge branch 'rs/commit-stack'Junio C Hamano
Code clean-up, unifying various hand-rolled "list of commit objects" and use the commit_stack API. * rs/commit-stack: commit-reach: use commit_stack commit-graph: use commit_stack commit: add commit_stack_grow() shallow: use commit_stack pack-bitmap-write: use commit_stack commit: add commit_stack_init() test-reach: use commit_stack remote: use commit_stack for src_commits remote: use commit_stack for sent_tips remote: use commit_stack for local_commits name-rev: use commit_stack midx: use commit_stack log: use commit_stack revision: export commit_stack
2026-01-12Merge branch 'sb/bundle-uri-without-uri'Junio C Hamano
Diagnose invalid bundle-URI that lack the URI entry, instead of crashing. * sb/bundle-uri-without-uri: bundle-uri: validate that bundle entries have a uri