summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2026-07-14repository: introduce repo_config_values_clear()Tian Yuchen3-0/+15
As part of the ongoing libification effort, dynamically allocated global configuration variables are being moved into 'struct repo_config_values'. To prevent memory leaks, we need a destructor to free these heap-allocated variables when a repository instance is torn down. Introduce 'repo_config_values_clear()' in environment.c and invoke it from 'repo_clear()' in repository.c. As a starting point, update this new function to handle the cleanup of 'attributes_file'. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com> Mentored-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Tian Yuchen <cat@malon.dev> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-14t1100: move creation of expected output into setup testShlok Kulshreshtha1-8/+7
The "expected" file is created at the top-level of the script, outside of any test. Code that runs outside of a test is not protected by the test harness: a failure there is not reported as a test failure and is easy to miss. Move the here-doc that creates "expected" into the existing setup test ("test preparation: write empty tree"), using a "<<-" here-doc so its body can be indented along with the rest of the test. Signed-off-by: Shlok Kulshreshtha <diy2903@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-14t1100: modernize test styleShlok Kulshreshtha1-20/+19
The tests in this script use the old style in which the test title and body are passed as separate backslash-continued arguments, with bodies indented using spaces: test_expect_success \ 'title' \ 'body' Convert them to the modern style in which the body is a single-quoted block on its own lines, indented with a tab: test_expect_success 'title' ' body ' While at it, remove an extraneous blank line between two tests. This is a style-only change; no test logic is modified. Signed-off-by: Shlok Kulshreshtha <diy2903@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13fast-export: standardize usage string and SYNOPSISChristian Couder3-3/+2
The output of `git fast-export -h` currently starts with: usage: git fast-export [<rev-list-opts>] while the SYNOPSIS section in this command's documentation shows: 'git fast-export' [<options>] | 'git fast-import' Let's make both of these consistent with each other and with other Git commands by describing the arguments with: [<options>] [<revision-range>] [[--] <path>...] This takes into account the following: - `git fast-export` accepts both rev-list arguments and a number of genuine options of its own (--[no-]progress, --[no-]signed-tags, --[no-]signed-commits, etc). - `git fast-export` was the only command using `[<rev-list-opts>]` while many other commands describe their revision arguments as `[<revision-range>] [[--] <path>...]`. - In the DESCRIPTION section of the documentation, it's already mentioned several times that the output should eventually be fed to `git fast-import`. This also enables us to remove fast-export from "t/t0450/adoc-help-mismatches". Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13The 2nd batch for Git 2.56Junio C Hamano1-0/+29
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13Merge branch 'ps/odb-generalize-prepare'Junio C Hamano11-64/+69
The 'reprepare()' callback for object database sources has been generalized into a 'prepare()' callback with an optional flush cache flag, and a new 'odb_prepare()' wrapper has been introduced to allow pre-opening object database sources. * ps/odb-generalize-prepare: odb: introduce `odb_prepare()` odb/source: generalize `reprepare()` callback
2026-07-13Merge branch 'kk/prio-queue-get-put-fusion'Junio C Hamano16-177/+139
The lazy priority queue optimization pattern (deferring actual removal in 'prio_queue_get()' to allow get+put fusion) has been folded directly into 'prio_queue' itself, speeding up commit traversal workflows and simplifying callers. * kk/prio-queue-get-put-fusion: prio-queue: fold lazy_queue into prio_queue for automatic get+put fusion prio-queue: rename .nr to .nr_ and add accessor helpers
2026-07-13Merge branch 'hn/branch-push-slip-advice'Junio C Hamano7-1/+144
When 'git push origin/main' or 'git branch origin main' is run, the command is now recognized as a potential typo, and advice has been added to offer a typo fix. * hn/branch-push-slip-advice: push: suggest <remote> <branch> for a slash slip branch: suggest <remote>/<branch> on upstream slip
2026-07-13Merge branch 'jk/format-patch-leakfix'Junio C Hamano2-3/+4
A memory leak in the '--base' handling of 'git format-patch' has been plugged, and the leak reporting of the test suite when running under a TAP harness has been improved. * jk/format-patch-leakfix: format-patch: fix leak of rev_info in prepare_bases() t: move LSan errors from stdout to stderr
2026-07-13Merge branch 'jk/reftable-leakfix'Junio C Hamano1-4/+4
A memory leak in the 'reftable_writer_new()' initialization function has been fixed by delaying the allocation of 'struct reftable_writer' until after input options are validated. * jk/reftable-leakfix: reftable: fix unlikely leak on API error
2026-07-13Merge branch 'ad/gpg-strip-cr-before-lf'Junio C Hamano1-14/+11
The GPG and SSH signature parsing code has been corrected to strip carriage return characters only when they immediately precede line feeds, instead of unconditionally stripping all carriage returns. * ad/gpg-strip-cr-before-lf: gpg-interface: fix strip_cr_before_lf to only remove CR before LF
2026-07-13odb: make optimizations pluggablePatrick Steinhardt6-489/+579
Move `odb_optimize()` and `odb_optimize_required()` from "builtin/gc.c" into the "files" source and wire them up via newly introduced vtable pointers for the object database sources. This makes the logic pluggable and thus allows other backends to have their own, custom implementation. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: fix signedness issues in ODB-related functionalityPatrick Steinhardt1-9/+11
There are a couple of signedness issues in ODB-related functionality. These are not a problem because we disable -Wsign-compare in this file, but once we move these functions into "odb/source-files.c" they will result in warnings. Fix those issues: - In `too_many_loose_objects()` we receive a signed limit, but compare it with the unsigned actual number of loose objects. This is fixed by bailing out immediately when the limit is smaller than or equal to zero, which we also do similarly in other places. The warning is then squelched via a cast. - In `find_base_packs()` we compare the signed size of the pack against the unsigned limit. As the pack size is always going to be a positive file size it's safe to cast it to an unsigned value. - In `odb_optimize()` we compare the unsigned `keep_pack.nr` value against the signed `gc_auto_pack_limit`. We only reach this code when `too_many_packs()` returns true-ish, and that can only happen when `gc_auto_pack_limit > 0`. Consequently, we can fix the warning by casting the limit to an unsigned value. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: refactor ODB optimizations to operate on "files" sourcePatrick Steinhardt1-38/+41
We have a couple of functions that are implementation details of how the "files" object database source performs optimizations. These functions often use global state like `the_repository` and implicitly derive the source they are supposed to optimize. Refactor these interfaces to accept a "files" source directly. This will make it easier to move around the whole logic into "odb/source-files.c" in a subsequent step. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: introduce `odb_optimize_required()`Patrick Steinhardt1-68/+92
When invoking either git-gc(1) or git-maintenance(1) with the "--auto" flag then we only perform those maintenance tasks that are actually required. This logic is inherently an implementation detail of the object database backend that's in use. But the logic is scattered around multiple different functions, which makes it hard to make the logic pluggable. Introduce a new `odb_optimize_required()` function that allows us to check these conditions in a generic way. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: move geometric repacking into `odb_optimize()`Patrick Steinhardt2-92/+95
We have two major object database optimization strategies: - The legacy strategy used by git-gc(1), which absorbs loose objects into packfiles, and eventually merges all packfiles once we have too many of them. - The more recent "geometric" strategy used by git-maintenance(1), which merges packfiles using a geometric sequence. These two strategies are still using completely separate code paths. In a subsequent commit we'll want to make both strategies pluggable though. Prepare for this change by merging the "geometric" strategy into `odb_optimize()`. This also allows us to reuse some of the logic we have in that function. Note that this change requires us to adapt tests because we're now using "-q" instead of "--quiet". Naturally though, these invocations are of course equivalent to one another. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: introduce object database optimization optionsPatrick Steinhardt1-60/+119
Introduce `struct odb_optimize_options` to decouple the options that are specific to optimizing the object database from `struct gc_config`. This structure will be moved into the object database layer in a subsequent commit. Note that there are a small set of backend-specific options in this structure. In an ideal world those of course wouldn't exist, but as we're introducing the object database abstractions retroactively we are somewhat forced to keep them. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: inline config values specific to the "files" backendPatrick Steinhardt1-62/+53
The `struct gc_config` contains a set of values that we read via the Git repository's configuration. Several of those values that are consumed by the object database optimization logic are inherently specific to the "files" config. In a later commit we'll make the logic to optimize object databases pluggable. So by carrying these "files"-backend specific values in the generic config struct means that other backends would have to worry about these values, too. This feels somewhat dirty, as implementation- specific details should live with the backends themselves. Inline these values directly at the call sites that need them instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: make repack arguments self-containedPatrick Steinhardt1-81/+75
When optimizing the object database most of the heavy-lifting is done by git-repack(1). The arguments we pass to this function are assembled in global scope, which is hard to follow. Refactor the logic by moving the vector into `maintenance_task_odb()`. While that means we have to pass more arguments to this function, it has the upside that the logic becomes self-contained without any kind of global interdependencies. This is a pure refactoring with no intended functional change. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: extract object database optimizations into separate functionPatrick Steinhardt1-30/+49
Extract the object database optimization logic from `cmd_gc()` into a new `maintenance_task_odb()` helper function. This is a pure refactoring with no intended functional change. Note that the message that notifies the user about too many loose objects is moved into the new function, as well. It is inherently an implementation detail of how the "files" source works, and as a consequence we'll move it around in a later commit, as well. This reordering means that the warning may now be printed at a different point in time, but it's not expected that this will have any practical implications. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13builtin/gc: move worktree and rerere tasks before object optimizationsPatrick Steinhardt1-7/+7
In subsequent patches we'll consolidate all tasks that relate to maintenance of the object database and move it into the "files" backend. The relevant code is somewhat scattered though, as several other tasks are interspersed between. Refactor the code so that all object database optimizations are grouped together, which requires us to move worktree pruning and rerere garbage collection around. In theory, rearranging this code can have an effect on the object database optimizations: - Rerere entries really shouldn't impact garbage collection at all, as these entries are not stored in the object database. - The index and HEAD reference of pruned worktrees may reference objects that become unreachable. That being said, the impact should be overall rather negligible. If the user was asking us to prune objects with immediate expiration time then we might now prune objects that were previously still kept alive by the worktree. But besides being a very specific edge case, it's arguably not even the wrong thing to also prune any potentially-unreachable objects immediately. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13odb: run "pre-auto-gc" hook for all maintenance tasksPatrick Steinhardt2-9/+152
The "pre-auto-gc" hook is supposed to run before auto-maintenance starts. The intent of this is to give users the ability to intercept running maintenance in case there's for example an event that is not supposed to run in parallel with repository maintenance. This hook runs via `need_to_gc()`, which is invoked via two paths: - It is called directly by git-gc(1). - It is called indirectly by git-maintenance(1) via the "gc" task. While the former makes sense, the latter is somewhat off. While the hook is indeed strongly tied to gc'ing a repository, the original intent of the hook is rather to inhibit any kind of automated garbage collection. That noticeably also includes all the other maintenance tasks that our new infrastructure may run, but those aren't getting intercepted at all. The move towards our new maintenance strategy has thus somewhat neutered the effectiveness of the hook. Fix this issue by running the hook before the first auto-maintenance task that would run as determined by the tasks's auto condition. Note that this requires us to lift the call to `run_hooks()` out of `needs_to_gc()`, as the hook would otherwise potentially run multiple times. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-13t7900: simplify how we check for maintenance tasksPatrick Steinhardt1-90/+100
We have several tests in t7900 that verify whether specific maintenance tasks did or did not run. This is done rather ad-hoc by checking for spawned Git commands, which is awfully fragile: - We have to adjust tests whenever arguments to the spawned Git commands change. - We don't have a way to verify that negative matches are still working as expected. - We rely on maintenance tasks spawning a Git command in the first place. We can do much better though, as we already have trace2 regions for each of the maintenance tasks. Introduce a helper function that extracts all such regions so that we can get a direct list of all maintenance tasks that a certain command ran. Adapt tests that care about whether or not a specific task ran to use this new helper. Note that many tests still use `test_subcommand` though, as they really care about the exact command that was executed. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-11t9811: replace 'test -f' and '! test -f' with 'test_path_*'Marcelo Machado Lage1-10/+10
Replace the basic shell commands 'test -f', with more modern test helpers 'test_path_is_file' and 'test_path_is_missing'. These modern helpers emit useful information when the corresponding tests fail, unlike 'test -f' and '! test -f'. The occurrences of '! test -f filename' were replaced by 'file_path_is_missing filename', a stronger guarantee equivalent to '! test -e filename'. Co-authored-by: Vinicius Lira de Freitas <vinilira@usp.br> Signed-off-by: Vinicius Lira de Freitas <vinilira@usp.br> Signed-off-by: Marcelo Machado Lage <marcelomlage@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-11t9811: break long && chains into multiple linesMarcelo Machado Lage1-5/+15
Rewrite single-line && chains by breaking them into multiple lines. Co-authored-by: Vinicius Lira de Freitas <vinilira@usp.br> Signed-off-by: Vinicius Lira de Freitas <vinilira@usp.br> Signed-off-by: Marcelo Machado Lage <marcelomlage@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-11builtin/add.c: replace run_command() with direct apply_all_patches() callGatla Vishweshwar Reddy2-7/+22
When the user runs "git add -e", the diff of the working tree changes is written to a temporary file, opened in an editor, and then applied back to the index. The application step is done by spawning a child process running "git apply --recount --cached <file>", which is an unnecessary subprocess since the apply machinery is available as a native C API. Replace the run_command() call with a direct call to apply_all_patches() using an initialized apply_state with the cached and recount options set appropriately. This avoids the overhead of forking a subprocess, keeps the operation within the same process, and makes the intent of the code clearer to the reader. Remove the now-unused includes of "run-command.h" and "strvec.h" since no other code in this file requires them after this change. Signed-off-by: Gatla Vishweshwar Reddy <gatlavishweshwarreddy26@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-11Merge branch 'kk/commit-reach-find-all-fix' into kk/merge-base-exhaustionJunio C Hamano2-3/+48
* kk/commit-reach-find-all-fix: commit-reach: guard !FIND_ALL early exit with generation ordering check t6600: add test for merge-base early exit with clock skew
2026-07-10object-file: fix closing object stream twicePatrick Steinhardt2-4/+18
In 10a6762719 (object-file: adapt `stream_object_signature()` to take a stream, 2026-02-23), we have refactored `stream_object_signature()` so that it doesn't create the stream ad-hoc anymore. Instead, callers are expected to pass in a stream, which allows them to construct the streams from different sources. While the stream was previously managed by `stream_object_signature()`, the full lifecycle is now owned by the caller. Hence, it's the caller's responsibility to close the stream, and the called function shouldn't do that anymore. And while the mentioned commit did drop one call that closed the stream, there's a second such call that was missed when reading from the stream fails. The consequence of this can be a double free of the stream. Fix the bug by dropping that leftover call to `odb_read_stream_close()`. Note that it was originally discussed whether this should be treated as a security vulnerability. But there are only two callers: once via `parse_object_with_flags()`, and once via `verify_packfile()`. Neither of these callers plays any role on the transport layer, so this issue is only relevant for objects that are already available via the local object database. Furthermore, a packfile that is corrupted in this way would be detected when receiving the packfile, so it's not easy for an adversary to plant such a packfile, either. Consequently, we decided that this is not covered as part of our threat model. Reported-by: xuqing yang <rigelyoung@icloud.com> Helped-by: Jeff King <peff@peff.net> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10builtin/receive-pack: stage incoming objects via ODB transactionsJustin Tobler1-33/+35
Objects received by git-receive-pack(1) are quarantined in a temporary "incoming" directory and migrated into the object database prior to the reference updates. The quarantine is currently managed through `tmp_objdir` directly. In a pluggable ODB future, how exactly an object gets written to a transaction may vary for a given ODB source. Refactor git-receive-pack(1) to use the ODB transaction interfaces to manage the object staging area in a more agnostic manner accordingly. Note that the ODB transaction is now responsible for managing the primary and alternate ODBs for the repository. One small change as a result is that the temporary directory is now applied as the primary ODB in the main process instead of an alternate. This does not change anything for git-receive-pack(1) though because it only needs access to the newly written objects and doesn't care how exactly it is set up. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10builtin/receive-pack: drop redundant tmpdir envJustin Tobler1-1/+0
When performing the connectivity checks for a shallow ref in `update_shallow_ref()`, the child process environment variables are populated via `tmp_objdir_env()`. This is unnecessary though as `update_shallow_ref()` is only reached after `tmp_objdir_migrate()` has been performed which means there is no longer a temporary directory that needs to be shared with child processes. Drop the call to `tmp_objdir_env()` accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10odb/transaction: introduce ODB transaction flagsJustin Tobler13-22/+61
The temporary directory used by git-receive-pack(1) to write objects is managed slightly differently than how it is done via ODB transactions: - The temporary directory is eagerly created upfront, instead of waiting for the first object write. - The prefix name of the temporary directory is "incoming" instead of "bulk-fsync". In a subsequent commit, git-receive-pack(1) will use ODB transactions instead of `tmp_objdir` directly. To provide a means to configure the same transaction behavior, introduce `enum odb_transaction_flags` and the ODB_TRANSACTION_RECEIVE flag intended as a signal for ODB transactions using the "files" backend to be set up for git-receive-pack(1). Transaction call sites are updated accordingly to provide the required flag parameter. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10odb/transaction: add transaction env interfaceJustin Tobler3-0/+41
The ODB transaction backend is responsible for creating/managing its own staging area for writing objects. Other child processes spawned by Git may need access to uncommitted objects or write new objects in the staging area though. Introduce `odb_transaction_env()` which is expected to provide the set of environment variables needed by a child process to access the transaction's staging area. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10odb/transaction: propagate commit errorsJustin Tobler2-6/+11
When `odb_transaction_commit()` is invoked, the return value of the backend commit callback is silently discarded. A backend has no way to signal that committing failed, such as when the "files" backend cannot migrate its temporary object directory into the permanent ODB. In a subsequent commit, git-receive-pack(1) starts using ODB transaction to stage objects and consequently cares about such failures so it can handle the error appropriately. Change the commit callback signature to return an int error code and have `odb_transaction_commit()` forward it accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10odb/transaction: propagate begin errorsJustin Tobler8-18/+45
When `odb_transaction_begin()` is invoked, the function returns the transaction pointer directly. There is no way for the backend to signal that it failed to set up its state, such as when creating the temporary object directory backing the transaction. In a subsequent commit, git-receive-pack(1) starts using ODB transactions and needs to be able to report such failures rather than silently ignore them. Refactor `odb_transaction_begin()` to return an int error code and write the resulting transaction into an out parameter. Also introduce `odb_transaction_begin_or_die()` as a convenience for callsites that do not need to handle errors explicitly. Note that `odb_transaction_begin()` now returns an error when the ODB already has an inflight transaction pending. ODB transaction call sites that may encounter an inflight transaction are updated to explicitly handle this case. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10object-file: propagate files transaction errorsJustin Tobler4-16/+26
The "files" transaction backend may encounter errors related to managing the temporary directory used to stage objects, but silently ignores these errors. Instead return errors encountered in the `odb_transaction_files_{prepare,begin,commit}()` interfaces to allow callers to handle them as needed. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10object-file: drop check for inflight transactionsJustin Tobler2-6/+1
ODB transactions are started via `odb_transaction_begin()` and contain validation to avoid starting multiple transactions at the same time. The "files" backend also has the same logic, but is redundant due to the generic layer already handling it. Drop this validation from the "files" backend accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10object-file: embed transaction flush logic in commit functionJustin Tobler1-36/+28
When a "files" transaction is committed, `flush_loose_object_transaction()` is invoked to handle performing a hardware flush along with migrating the temporary object directory into the primary and configuring the repository ODB source accordingly. The function name here is a bit misleading because the helper is doing a bit more than just "flushing" the transaction contents. Also, in a subsequent commit, the transaction temporary directory is used to stage packfiles and not just loose objects anymore. Lift the helper function logic into `odb_transaction_files_commit()` to more accurately signal to readers the operation being performed. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10object-file: rename files transaction fsync functionJustin Tobler1-6/+10
When writing an object to a "files" ODB transaction, a full hardware flush is not initially performed during the fsync in `fsync_loose_object_transaction()` and instead delayed until the transaction is later committed. To be more consistent with other "files" ODB transaction helpers, rename the function to `odb_transaction_files_fsync()` accordingly. The conditional in the helper is also slightly restructured to improve clarity to readers. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10object-file: rename files transaction prepare functionJustin Tobler1-3/+3
The "files" ODB transaction backend lazily creates a temporary object directory when the first loose object is written to the transaction via `prepare_loose_object_transaction()`. In a subsequent commit, the temporary directory is used to also write packfiles to. Rename the function to `odb_transaction_files_prepare()` accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10b4: include change-id in cover templateChen Linxuan1-0/+1
With b4 0.15.2, I hit a local failure after sending a series with the in-tree cover template. The generated sent/<change-id>-vN tag contained base-commit, but did not contain change-id, and later b4 commands failed when trying to read it: CRITICAL: Tag sent/... does not contain change-id info Looking at b4's source, the sent tag message is derived from the rendered cover letter. The same code later parses that tag and expects both base-commit and change-id to be present. The default b4 cover template has both trailers, but our in-tree template only has base-commit. Add the missing change-id trailer next to base-commit so sent tags produced from the project template remain readable by b4's reroll and comparison logic. Signed-off-by: Chen Linxuan <me@black-desk.cn> Acked-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10config: add "worktree" and "worktree/i" includeIf conditionsChen Linxuan3-0/+187
The includeIf mechanism already supports matching on the .git directory path (gitdir) and the currently checked out branch (onbranch). But in multi-worktree setups the .git directory of a linked worktree points into the main repository's .git/worktrees/ area, which makes gitdir patterns cumbersome when one wants to include config based on the working tree's checkout path instead. Introduce two new condition keywords: - worktree:<pattern> matches the realpath of the current worktree's working directory (i.e. repo_get_work_tree()) against a glob pattern. This is the path returned by git rev-parse --show-toplevel. - worktree/i:<pattern> is the case-insensitive variant. The implementation reuses the include_by_path() helper introduced in the previous commit, passing the worktree path in place of the gitdir. The condition never matches in bare repositories (where there is no worktree) or during early config reading (where no repository is available). Add documentation describing the new conditions, including a comparison with extensions.worktreeConfig and a note that worktree matching currently uses the realpath-resolved worktree location. Add tests covering bare repositories, multiple worktrees, realpath-resolved symlinked worktree paths, case-sensitive and case-insensitive matching, early config reading, and non-repository scenarios. Signed-off-by: Chen Linxuan <me@black-desk.cn> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10config: refactor include_by_gitdir() into include_by_path()Chen Linxuan1-11/+8
The include_by_gitdir() function matches the realpath of a given path against a glob pattern, but its interface is tightly coupled to the gitdir condition: it takes a struct config_options *opts and extracts opts->git_dir internally. Refactor it into a more generic include_by_path() helper that takes a const char *path parameter directly, and update the gitdir and gitdir/i callers to pass opts->git_dir explicitly. No behavior change, just preparing for the addition of a new worktree condition that will reuse the same path-matching logic with a different path. Signed-off-by: Chen Linxuan <me@black-desk.cn> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10reftable: fix quadratic behavior in the presence of tombstonesKristofer Karlsson3-12/+46
When many tombstones are present in a reftable, operations that need to look up or iterate over refs exhibit quadratic behavior. With 8000 refs deleted and re-created, update-ref takes ~15s, quadrupling for each doubling of input size. The root cause is the merged iterator's suppress_deletions flag. When set, merged_iter_next_void() silently consumes tombstone records in a tight internal loop before returning to the caller. This prevents higher-level code from checking iteration bounds (such as prefix or refname comparisons) until after all tombstones have been scanned. This affects any code path that seeks into a range containing tombstones, including: - refs_verify_refnames_available() seeks to "refs/tags/foo-1/" to check for D/F conflicts and must scan through all subsequent tombstones before the caller can see that they are past the prefix of interest. - reftable_backend_read_ref() seeks to a specific refname and must scan through all subsequent tombstones before returning "not found", because the merged iterator skips the matching tombstone and searches for the next live record. Fix this by making suppress_deletions configurable via reftable_stack_options instead of unconditionally enabling it. Git no longer sets the flag, so tombstones are now returned to callers in the reftable backend, which skip them after their existing bounds checks. This allows iteration to terminate as soon as a tombstone past the relevant bound is encountered. Downstream users of the reftable library (e.g. libgit2) can still enable suppress_deletions through the stack options to retain the previous behavior. This also requires adding deletion checks to the log iteration paths, since suppress_deletions applied to both ref and log iterators. Both tests in p1401 go from ~13s to ~0.2s with this change. Reported-by: Jeff King <peff@peff.net> Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10t/perf: add perf test for ref tombstone scenariosKristofer Karlsson1-0/+46
Add performance tests for update-ref when many tombstones are present in a reftable. The first test exercises the scenario where all refs are deleted (creating tombstones) and then re-created with the same names, which currently exhibits quadratic behavior. The second test uses a separate repository with an asymmetric variant where refs are deleted and then new, differently-named refs are created. When the tombstones sort after the new refs, every create scans all tombstones, making this case even worse than re-creating the same refs. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10shallow: give write_one_shallow() its own hex bufferJohannes Schindelin1-1/+3
The previous fix reuses the local `hex` variable that is already computed at the top of `write_one_shallow()`. That works today, but `oid_to_hex()` returns a pointer into a small rotating buffer, so it is not stable across an unrelated call to `oid_to_hex()` from the same thread. A future edit that adds such a call between the assignment and the last user of `hex` would silently corrupt the output. Move `write_one_shallow()` off the rotating buffer entirely by using a local buffer instead. The current users of that `hex` variable are unchanged. Suggested-by: Junio C Hamano <gitster@pobox.com> Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10shallow: fix NULL dereferenceJohannes Schindelin1-2/+1
After `write_one_shallow()` calls `lookup_commit()` to find the commit object for a shallow graft entry, it then checks `if (!c || ...)`. Inside that block, when the VERBOSE flag is set, it prints the OID being removed, via `c->object.oid`. But `c` can be NULL (the first condition in the `||` check). This happens when a shallow graft entry references a commit object that is not in the object store (e.g., after a partial fetch or in a corrupted repository). In that case, `lookup_commit()` returns NULL because the object cannot be found, the SEEN_ONLY check correctly decides to remove this entry from .git/shallow, but the verbose message crashes before the removal can complete. Use `graft->oid` instead of `c->object.oid` for the message. The graft entry's OID is the same value (it was used as the lookup key) and is always available regardless of whether the commit object exists. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10bisect: ensure non-NULL `head` before using itJohannes Schindelin1-1/+3
When `refs_resolve_ref_unsafe()` is called to resolve HEAD, and returns NULL (e.g., HEAD does not exist as a proper ref), the code falls back to `repo_get_oid("HEAD")` to try to resolve the OID directly. If that succeeds, execution continues with `head` still set to NULL. Later, that variable is passed to `repo_get_oid()` and `starts_with()`, both of which would dereference the NULL pointer. A concrete trigger for `refs_resolve_ref_unsafe()` returning NULL while `repo_get_oid()` succeeds could not be constructed against the ref backends currently in the tree; the naive case (a symbolic HEAD pointing at a nonexistent branch, in either the files or the reftable backend) fails in both calls consistently and returns via the existing `error(_("bad HEAD - I need a HEAD"))` path. Coverity, however, flags the leftover use of `head` after the outer `if (!head)` on a formal reading: `head` is still NULL at that point, and both `starts_with(head, ...)` and the second `repo_get_oid(..., head, ...)` in the else-branch would dereference it if that state were ever reached. Removing the outer check would risk regressing to a crash if a future ref backend ever manages to hit the "returns NULL for HEAD but has a valid OID for HEAD" state. Assigning the literal string "HEAD" as a safe fallback documents the intent and satisfies the analyzer without changing behavior in any code path we can currently reach. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10pack-bitmap: handle missing bitmap for base MIDXJohannes Schindelin1-0/+4
When `prepare_midx_bitmap_git()` is called to load the bitmap for a chained MIDX's base layer, if the base MIDX does not have an associated bitmap file (e.g., it was not generated, or was deleted by gc), the return value is NULL. It is then stored in `bitmap_git->base` and immediately dereferenced on the next line. This can happen in practice with incremental MIDX chains: the base MIDX may have been written without `--write-bitmap-index`, or the bitmap may have been pruned while the incremental layer's bitmap still references it. Check the return value and go to the cleanup label (which unmaps the current bitmap and returns -1) so the caller falls back to non-bitmap object enumeration, matching the handling of other bitmap loading failures in the same function. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10revision: avoid dereferencing NULL in `add_parents_only()`Johannes Schindelin2-2/+25
This function resolves revision suffixes like commit^@ (all parents), commit^! (commit minus parents), and commit^-N (exclude Nth parent). It calls `get_reference()` in a loop to peel through tag objects until it reaches a commit. The existing NULL check after `get_reference()` only handles the ignore_missing case, but get_reference() can return NULL through three distinct paths: 1. revs->ignore_missing: the caller asked to silently skip missing objects. 2. revs->exclude_promisor_objects: the object is a lazy promisor object that should be excluded from the walk. 3. revs->do_not_die_on_missing_objects: the caller wants to record missing OIDs for later reporting (used by `git rev-list --missing=print`) rather than dying. In the latter two instances, the code falls through to dereference the NULL pointer. Handle all three cases explicitly: - ignore_missing: return 0, matching the existing behavior and the pattern in `handle_revision_arg()`. - do_not_die_on_missing_objects: return 0. The missing OID has already been recorded in `revs->missing_commits` by `get_reference()`. Returning 0 is consistent with `handle_revision_arg()` and `process_parents()`, both of which continue without error when this flag is set. The broader codebase pattern for this flag is "record and continue": list-objects.c, builtin/rev-list.c, and process_parents all skip the die/error and keep walking. - everything else (only the `exclude_promisor_objects` case in practice): return -1, consistent with `handle_revision_arg()` where the condition only matches `ignore_missing` or `do_not_die_on_missing_objects`, falling through to ret = -1 for the promisor case. Note: the callers of `add_parents_only()` in `handle_revision_pseudo_opt()` treat any nonzero return as "handled" (`if (add_parents_only(...)) { ret = 0; }`), so the -1 for the promisor case is indistinguishable from success there. This means a promisor-excluded tag target referenced via commit^@ would be silently skipped rather than producing an error. This is a pre-existing limitation of the caller's return value handling and not made worse by this change; the alternative (a NULL dereference crash) _would be_ strictly worse. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-10replay: die when --onto does not peel to a commitJohannes Schindelin1-2/+6
The `peel_committish()` function calls `repo_peel_to_type()` to convert the given object to a commit, but does not check the return value. When the object exists but cannot be peeled to a commit (e.g., a tree or blob OID is passed as --onto), the return value is NULL. Add an explicit NULL check and die with a descriptive message in that case. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>