summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2026-05-19setup: stop using `the_repository` in `setup_work_tree()`Patrick Steinhardt21-42/+38
Stop using `the_repository` in `setup_work_tree()` and instead accept the repository as a parameter. The injection of `the_repository` is thus bumped one level higher, where callers now pass it in explicitly. Note that the function tracks two bits of information via global variables. This of course doesn't make much sense anymore now that we can set up worktrees for arbitrary repositories: - We track whether the worktree has already been initialized and, if so, we skip the call to `chdir_notify()` and setenv(3p). It does not make much sense to store this info in the repository, as we _would_ want to update the environment when switching between worktrees back and forth. So instead of storing this info in the repository, we drop this state entirely and live with the fact that we may execute the logic twice. It should ultimately be idempotent though and thus not be much of a problem. - We track whether the worktree configuration is bogus. If so, and if later on some caller tries to setup the worktree, then we'll die instead. This is indeed information that we can move into the repository itself. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: stop using `the_repository` in `enter_repo()`Patrick Steinhardt7-9/+9
Stop using `the_repository` in `enter_repo()` and instead accept the repository as a parameter. The injection of `the_repository` is thus bumped one level higher, where callers now pass it in explicitly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: stop using `the_repository` in `verify_non_filename()`Patrick Steinhardt6-8/+8
Stop using `the_repository` in `verify_non_filename()` and instead accept the repository as a parameter. The injection of `the_repository` is thus bumped one level higher, where callers now pass it in explicitly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: stop using `the_repository` in `verify_filename()`Patrick Steinhardt6-8/+10
Stop using `the_repository` in `verify_filename()` and instead accept the repository as a parameter. The injection of `the_repository` is thus bumped one level higher, where callers now pass it in explicitly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: stop using `the_repository` in `path_inside_repo()`Patrick Steinhardt3-5/+5
Stop using `the_repository` in `path_inside_repo()` and instead accept the repository as a parameter. The injection of `the_repository` is thus bumped one level higher, where callers now pass it in explicitly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: stop using `the_repository` in `prefix_path()`Patrick Steinhardt12-23/+26
Stop using `the_repository` in `prefix_path()` and instead accept the repository as a parameter. The injection of `the_repository` is thus bumped one level higher, where callers now pass it in explicitly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: stop using `the_repository` in `is_inside_work_tree()`Patrick Steinhardt6-17/+20
Similar as with the preceding commit, `is_inside_work_tree()` determines whether the current working directory is located inside the worktree of `the_repository`. Perform the same refactoring by dropping the caching mechanism and injecting the repository that shall be checked. Note that, same as in the preceding commit, we're also resolving the worktree path via `realpath()`. In theory this step is not necessary as we always set the worktree path via `repo_set_worktree()`, and that function already resolves the path for us. But resolving the path a second time is unlikely to matter performance-wise, and it feels fragile to rely on the repository's worktree path being absolute. We thus perform the same extra step even though it's ultimately not required. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: stop using `the_repository` in `is_inside_git_dir()`Patrick Steinhardt3-10/+8
The function `is_inside_git_dir()` verifies whether or not the current working directory is located inside the gitdir of `the_repository`. This is done by taking the gitdir path and verifying that it's a prefix of the current working directory. This information is cached so that we don't have to re-do this change multiple times. Furthermore, we proactively set the value in multiple locations so that we don't even have to perform the check when we have discovered the repository. While we could simply move the caching variable into the repository, the current layout doesn't really feel sensible in the first place: - It can easily lead to false positives or negatives if at any point in time we may switch the current working directory. - We don't call the function in a hot loop, and neither is it overly expensive to compute. Drop the caching infrastructure and instead compute the property ad-hoc via an injected repository. Note that there is one small gotcha: we often end up with relative gitdir paths, and if so `is_inside_dir()` might fail. This wasn't an issue before because of how we proactively set the cached value during repository discovery. Now that we stop doing that it becomes a problem though, which we work around by resolving the gitdir via `realpath()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19setup: replace use of `the_repository` in static functionsPatrick Steinhardt1-88/+100
Replace the use of `the_repository` in "setup.c" for all static functions. For now, we simply add `the_repository` to invocations of these functions. This will be addressed in subsequent commits, where we'll move up `the_repository` one more layer to callers of "setup.c". Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19connect: use "service" enum for "name" argumentJeff King9-28/+58
The git_connect() function takes a "name" argument which is a bit confusing. It is _not_ the program to run on the remote repo, which is specified by the "prog" argument. It should instead be one of a few well-known strings specifying the type of operation (e.g., "git-upload-pack"). But to add to the confusion, unless otherwise configured, those well-known strings will also be the same as the programs we run, making it easy to mistake which variable is which. This confusion comes from eaa0fd6584 (git_connect(): fix corner cases in downgrading v2 to v0, 2023-03-17), though in its defense, the term "name" and the use of a string are found in other connect code, going all the way back to b236752a87 (Support remote archive from all smart transports, 2009-12-09). But let's see if we can clean things up a bit. The term "name" is overly vague. We use "service" in other places, including in the smart-http protocol, so let's use it here, too. Using a string invites the notion that it can be anything, not one of a defined set. Let's instead introduce an enum, which has the added bonus that the compiler can catch typos for us, rather than quietly choosing the wrong service from an unexpected strcmp() result. We do still have to turn our enum into those well-known strings to pass along in the remote-helper protocol (e.g., for a stateless-connect directive). But now we do so explicitly and in a way that I think is much more obvious to follow. This is a pure cleanup; there should be no behavior change. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19quote: simplify internals of dequotingJeff King1-14/+2
Our sq_dequote_to_argv_internal() helper was wrapped by the to_argv() and to_strvec() forms. Now that we have only the latter, we can stop wrapping it and drop the argv-only bits. Note that in theory sq_dequote_to_strvec() could take a const input string, which would be friendlier to its callers. We couldn't do that with the to_argv() form because it reused the input string to hold the output elements. But since we're built on sq_dequote_step(), which munges the input, we'd have to rework the parser. Since no callers care about it currently, we'll leave that for another day. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19quote: drop sq_dequote_to_argv()Jeff King2-14/+3
The last caller went away in f9dbb64fad (config: parse more robust format in GIT_CONFIG_PARAMETERS, 2021-01-12), when we switched to using sq_dequote_step(). The "to_argv()" form is not a great interface. If you care about raw speed, then sq_dequote_step() lets you work incrementally without extra allocations. If you care about simplicity, then sq_dequote_to_strvec() puts the result in an encapsulated data structure. With sq_dequote_to_argv(), you have a data dependency on the original string but still have to remember to manually free the argv array itself (but not its elements). So it's sort of a worst-of-both-worlds middle ground. Let's get rid of it. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19quote.h: bump strvec forward declaration to the topJeff King1-1/+1
We usually put forward declarations at the top of header files, rather than next to the functions that need them. In theory placing it next to the function has some explanatory value, but it's also just as likely to become stale if other uses are added. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19The 4th batchJunio C Hamano1-0/+32
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19Merge branch 'sj/submodule-update-clone-config-fix'Junio C Hamano2-1/+9
The configuration variable submodule.fetchJobs was not read correctly, which has been corrected. * sj/submodule-update-clone-config-fix: submodule-config: fix reading submodule.fetchJobs
2026-05-19Merge branch 'rs/sideband-clear-line-before-print'Junio C Hamano1-10/+12
Tweak the way how sideband messages from remote are printed while we talk with a remote repository to avoid tickling terminal emulator glitches. * rs/sideband-clear-line-before-print: sideband: clear full line when printing remote messages
2026-05-19Merge branch 'ag/rebase-update-refs-limit-to-branches'Junio C Hamano2-1/+25
"git rebase --update-refs", when used with an rebase.instructionFormat with "%d" (describe) in it, tried to update local branch HEAD by mistake, which has been corrected. * ag/rebase-update-refs-limit-to-branches: rebase: ignore non-branch update-refs
2026-05-19Merge branch 'kh/doc-restore-double-underscores-fix'Junio C Hamano1-1/+1
Doc update. * kh/doc-restore-double-underscores-fix: doc: restore: remove double underscore
2026-05-19Merge branch 'kh/doc-commit-graph'Junio C Hamano2-0/+13
Ramifications of turning off commit-graph has been documented a bit more clearly. * kh/doc-commit-graph: doc: add caveat about turning off commit-graph
2026-05-19Merge branch 'kh/name-rev-custom-format'Junio C Hamano10-26/+706
A new builtin "git format-rev" is introduced for pretty formatting one revision expression per line or commit object names found in running text. * kh/name-rev-custom-format: format-rev: introduce builtin for on-demand pretty formatting name-rev: make dedicated --annotate-stdin --name-only test name-rev: factor code for sharing with a new command name-rev: run clang-format before factoring code name-rev: wrap both blocks in braces
2026-05-19Merge branch 'sg/t6112-unwanted-tilde-expansion-fix'Junio C Hamano1-3/+3
Test fix. * sg/t6112-unwanted-tilde-expansion-fix: t6112: avoid tilde expansion
2026-05-19Merge branch 'en/xdiff-cleanup-3'Junio C Hamano4-32/+73
Preparation of the xdiff/ codebase to work with Rust. * en/xdiff-cleanup-3: xdiff/xdl_cleanup_records: make execution of action easier to follow xdiff/xdl_cleanup_records: make setting action easier to follow xdiff/xdl_cleanup_records: make limits more clear xdiff/xdl_cleanup_records: use unambiguous types xdiff: use unambiguous types in xdl_bogo_sqrt() xdiff/xdl_cleanup_records: delete local recs pointer
2026-05-19Merge branch 'mc/http-emptyauth-negotiate-fix'Junio C Hamano5-5/+124
The 'http.emptyAuth=auto' configuration now correctly attempts Negotiate authentication before falling back to manual credentials. This allows seamless Kerberos ticket-based authentication without requiring users to explicitly set 'http.emptyAuth=true'. * mc/http-emptyauth-negotiate-fix: doc: clarify http.emptyAuth values t5563: add tests for http.emptyAuth with Negotiate http: attempt Negotiate auth in http.emptyAuth=auto mode http: extract http_reauth_prepare() from retry paths
2026-05-19use __builtin_add_overflow() in st_add() with ClangRené Scharfe1-2/+20
Clang and GCC optimize away comparisons of overflow checks by checking the carry flag on x64. GCC does the same on ARM64, but Clang currently (version 22.1) doesn't. It does this optimization for overflow checks that use its builtin function __builtin_add_overflow(), though. Provide a non-generic lookalike for size_t that does the same checks as before as a fallback and use the original with Clang. Use it on all platforms for simplicity. On an Apple M1 I get a nice speedup for a command that builds lots of strings using a strbuf, which exercises the st_add3() in strbuf_grow() for every line of output: Benchmark 1: ./git_main cat-file --batch-all-objects --batch-check='%(objectname)' Time (mean ± σ): 120.4 ms ± 0.2 ms [User: 113.8 ms, System: 6.0 ms] Range (min … max): 120.1 ms … 121.1 ms 24 runs Benchmark 2: ./git cat-file --batch-all-objects --batch-check='%(objectname)' Time (mean ± σ): 115.5 ms ± 0.1 ms [User: 108.6 ms, System: 5.8 ms] Range (min … max): 115.2 ms … 115.8 ms 25 runs Summary ./git cat-file --batch-all-objects --batch-check='%(objectname)' ran 1.04 ± 0.00 times faster than ./git_main cat-file --batch-all-objects --batch-check='%(objectname)' Suggested-by: Jeff King <peff@peff.net> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-19strbuf: use st_add3() in strbuf_grow()René Scharfe1-4/+2
Simplify the code by calling st_add3() to do overflow checks instead of open-coding it. This changes the error message to include the offending summands, which can be helpful when tracking down the cause. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-18config: retry acquiring config.lock, configurable via core.configLockTimeoutJörg Thalheim5-5/+53
Concurrent config writers race for the ".lock" file, which is taken with open(O_EXCL) and no retry, so the losers fail right away with "could not lock config file". This shows up with parallel "git worktree add -b" against the same repository: each one writes a couple of branch.* keys and the losers fail at random. Worse, "git worktree add" doesn't propagate that failure to its exit code, so the tracking config is silently dropped. (The swallowed error is a separate bug.) Retry instead of giving up on the first EEXIST. The lock is only held while rewriting a small file, so the loser only has to wait out the other writers. Same approach as 4ff0f01cb7 (refs: retry acquiring reference locks for 100ms, 2017-08-21). On the semantics: the on-disk config is read only after the lock is taken, so writers touching different keys can't lose each other's change. Writers touching the same key still get last-writer-wins, but that is already the case today and would need a compare-and-swap config API to fix. The retry only turns hard failures into successes. Default to 1000ms, like core.packedRefsTimeout: same shape of problem, one shared file everyone serializes through. A larger timeout only costs anything when a stale lock is left behind by a crash, which is rare; a smaller one fails spuriously on slow filesystems (NTFS has been seen needing more than 100ms). Make it configurable as core.configLockTimeout. There is no chicken-and-egg problem: we read the config before we lock it. microsoft/git carries a similar patch (core.configWriteLockTimeoutMS, default off) for Scalar's tests. Defaulting to non-zero here because the worktree case fails silently. Helped-by: Patrick Steinhardt <ps@pks.im> Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Jörg Thalheim <joerg@thalheim.io> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-18refs/files: skip lock files during consistency checksKarthik Nayak2-11/+52
Consistency checks in the files reference backend involve two steps: 1. Iterate over all entries within the 'refs/' directory and call `files_fsck_ref()` on each. 2. Iterate over all root refs via `for_each_root_ref()` and call `files_fsck_ref()` on each. `files_fsck_ref()` then runs all fsck checks defined in `fsck_refs_fn[]`. Step 2 goes through the refs API and only sees valid refs, but step 1 iterates the directory directly and may also encounter intermediate '*.lock' files. Currently, `files_fsck_refs_name()`, one of the functions in `fsck_refs_fn[]`, filters out lock files itself. The other function, `files_fsck_refs_content()`, has no such check and would parse the lock file. Any new function added to `fsck_refs_fn[]` would have the same problem. Move the filter up into `files_fsck_refs_dir()`, where the directory iteration happens. Since step 2 cannot produce lock files, this is the only site where the filter is needed, and individual checks no longer have to re-implement it. Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-17The 3rd batchJunio C Hamano1-7/+28
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-17Merge branch 'rs/grep-column-only-match-fix'Junio C Hamano2-4/+5
"git grep" update. * rs/grep-column-only-match-fix: grep: fix --column --only-match for 2nd and later matches
2026-05-17Merge branch 'hn/git-checkout-m-with-stash'Junio C Hamano16-180/+343
"git checkout -m another-branch" was invented to deal with local changes to paths that are different between the current and the new branch, but it gave only one chance to resolve conflicts. The command was taught to create a stash to save the local changes. * hn/git-checkout-m-with-stash: checkout -m: autostash when switching branches checkout: rollback lock on early returns in merge_working_tree sequencer: teach autostash apply to take optional conflict marker labels sequencer: allow create_autostash to run silently stash: add --label-ours, --label-theirs, --label-base for apply
2026-05-17Merge branch 'pw/rename-to-get-current-worktree'Junio C Hamano3-3/+3
Code clean-up. * pw/rename-to-get-current-worktree: worktree: rename get_worktree_from_repository()
2026-05-17Merge branch 'mf/format-patch-cover-letter-format-docfix'Junio C Hamano1-1/+1
Docfix. * mf/format-patch-cover-letter-format-docfix: Fix docs for format.commitListFormat
2026-05-17Merge branch 'en/ort-cached-rename-with-trivial-resolution'Junio C Hamano2-26/+82
"ort" merge backend improvements. * en/ort-cached-rename-with-trivial-resolution: merge-ort: handle cached rename & trivial resolution interaction better
2026-05-17Merge branch 'ss/t7004-unhide-git-failures'Junio C Hamano1-21/+23
Test clean-up. * ss/t7004-unhide-git-failures: t7004: avoid subshells to capture git exit codes t7004: dynamically grab expected state in tests t7004: drop hardcoded tag count for state verification
2026-05-17Merge branch 'en/backfill-fixes-and-edges'Junio C Hamano3-10/+153
The 'git backfill' command now rejects revision-limiting options that are incompatible with its operation, uses standard documentation for revision ranges, and includes blobs from boundary commits by default to improve performance of subsequent operations. * en/backfill-fixes-and-edges: backfill: default to grabbing edge blobs too backfill: document acceptance of revision-range in more standard manner backfill: reject rev-list arguments that do not make sense
2026-05-17stash: add coverage for show --include-untrackedPushkar Singh1-0/+17
Add a test for 'git stash show --include-untracked' to cover the case where untracked files saved in the stash are included in the output. While stash creation and restoration of untracked files are already tested, there is currently no explicit test covering the output behavior of 'stash show --include-untracked'. Signed-off-by: Pushkar Singh <pushkarkumarsingh1970@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-17t6600: add tests for duplicate tips in tips_reachable_from_bases()Kristofer Karlsson1-0/+45
When multiple refs point to the same commit, the reachability check must handle them correctly. Add three tests: - duplicate tips, all reachable - duplicate tips, none reachable - duplicate tips at the minimum generation (exercises the early-termination advancement logic) Suggested-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-17commit-reach: use object flags for tips_reachable_from_bases()Kristofer Karlsson1-12/+11
tips_reachable_from_bases() walks the commit graph from a set of base commits to find which tip commits are reachable. The inner loop does a linear scan over the tips array to check whether each visited commit is a tip, making the overall cost O(C * T) where C is commits walked and T is the number of tips. Use the RESULT object flag to mark tip commits, replacing the linear scan with a single flag test per visited commit. This reduces the per-commit tip check from O(T) to O(1) and the overall cost from O(C * T) to O(C + T). When multiple refs point to the same commit, the shared object gets the flag once, so all duplicates are handled automatically. The early-termination advancement loop checks the flag on the sorted commits array directly, which naturally handles duplicates since the flag is on the shared commit object. This also removes the index field from struct commit_and_index, since the indirection through the original tips array is no longer needed. This function is called by `git for-each-ref --merged` and `git branch/tag --contains/--no-contains` via reach_filter() in ref-filter.c. Benchmark on a merge-heavy monorepo (2.3M commits, 10,000 refs): Command Before After Speedup for-each-ref --merged HEAD 6.57s 1.59s 4.1x for-each-ref --no-merged HEAD 6.67s 1.66s 4.0x branch --merged HEAD 0.68s 0.61s 10% branch --no-merged HEAD 0.65s 0.61s 8% tag --merged HEAD 0.12s 0.12s - On linux.git with 10,000 synthetic branches at the root commit (worst case for the DFS walk): Command Before After Speedup for-each-ref --merged HEAD 1.35s 0.35s 3.9x for-each-ref --no-merged HEAD 1.82s 0.31s 5.9x The large speedup for for-each-ref is because it checks all 10,000 refs as tips, making the O(T) inner loop expensive. The branch subcommand only checks local branches (fewer tips), so the improvement is smaller. Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-16diff-format.adoc: mode and hash are 0* for unmerged paths from index onlyPhilippe Blain1-4/+4
In the "Raw output format" section, we mention that the 'mode' and 'sha1' for "src" and "dst" are 0* if "(creation|deletion) or unmerged". For unmerged entries, 'mode' and 'sha1' are in fact 0* only when we are looking at the index, i.e. on the left side for 'git diff-files' and on the right side for 'git diff-index --cached'. Be more precise by mentioning this, and while at it uniformize the wording of the "work tree out of sync with the index" case. Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-16diff-format.adoc: 'git diff-files' prints two lines for unmerged filesPhilippe Blain1-1/+3
Since 10637b84d9 (diff-files: -1/-2/-3 to diff against unmerged stage., 2005-11-29), for unmerged entries 'git diff-files' print both an "unmerged" line ('U'), as well as an "in-place edit" line ('M') comparing stage 2 (by default) with the working tree. The "Raw output format" documentation however mentions that all commands print a single line per changed file. Adjust diff-format.adoc to also mention this special case, for completeness. Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-16diff-format.adoc: remove mention of diff-tree specific outputPhilippe Blain1-3/+1
In the "Raw output format" section, we start by mentioning that 'git diff-tree' prints the hashes of what is being compared. This is only true in --stdin mode, and is already mentioned in the description of '--stdin' in git-diff-tree.adoc. Remove this sentence such that we only focus on the common output between diff-tree, diff-index, diff-files and Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-16generate-configlist: collapse depfile for older NinjaToon Claes1-1/+4
The tools/generate-configlist.sh script generates two files: * config-list.h * config-list.h.d The former is included by the source code and the latter defines on which files the former depends. The contents of `config-list.h.d` consists of two sections: config-list.h: Documentation/config.adoc config-list.h: Documentation/git-config.adoc config-list.h: Documentation/config/add.adoc config-list.h: Documentation/config/advice.adoc config-list.h: Documentation/config/alias.adoc config-list.h: Documentation/config/am.adoc config-list.h: Documentation/config/apply.adoc ... This first section actually defines on which individual files `config-list.h` depends and thus needs to be rebuild if one of those changes. And the second section contains content like: Documentation/config.adoc: Documentation/git-config.adoc: Documentation/config/add.adoc: Documentation/config/advice.adoc: Documentation/config/alias.adoc: Documentation/config/am.adoc: Documentation/config/apply.adoc: ... These rules exist to ensure Make won't fail with the following error if one of the .adoc files is renamed or removed: make: *** No rule to make target 'Documentation/config.adoc', needed by 'config-list.h'. With the no-op targets defined in `config-list.h.d`, Make knows there's no work to be done to generate these files, so it doesn't error out if it doesn't exist. For the Makefile build system this works great. And since ebeea3c471 (build: regenerate config-list.h when Documentation changes, 2026-02-24) this script is also called from the Meson build system. Nevertheless, on AlmaLinux 8 the following build failure is seen: ninja: error: dependency cycle: config-list.h -> config-list.h This version of this distro uses Ninja 1.8.2 and it seems to have some issues with the format of the `config-list.h.d` file. Ninja versions before 1.10.0 do not reset the depfile parser state on newlines. This causes issues when the depfile has one dependency per line, like we have in `config-list.h.d`: config-list.h: Documentation/config.adoc config-list.h: Documentation/config/add.adoc The parser only recognizes the first "config-list.h:" as a target. On subsequent lines it is still in dependency-parsing mode, so the repeated output name is recorded as an input. This causes the error mentioned above. The bug in Ninja is fixed in 1.10, with commit ninja-build/ninja@1daa7470ab7e (depfile_parser: remove restriction on multiple outputs, 2019-11-20). To be compatible with older versions of Ninja, collapse the dependencies for `config-list.h` into a single line like: config-list.h: Documentation/config.adoc Documentation/config/add.adoc ... This works around the bug in older versions of Ninja, and is fully compatible Make and with more recent versions of Ninja. And while the no-op targets are not needed for Ninja, they also don't do any harm. Helped-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-16Merge branch 'ed/check-connected-close-err-fd-2.53' into ↵Junio C Hamano1-0/+2
ed/check-connected-close-err-fd Avoid leaving err file descriptor open when check_connected() returns. * ed/check-connected-close-err-fd-2.53: connected: close err_fd in promisor fast-path
2026-05-16connected: close err_fd in promisor fast-pathEthan Dickson1-0/+2
connected.h documents that err_fd is closed before check_connected() returns. It is, on three of four exit paths. The promisor-pack fast path added in 50033772d (connected: verify promisor-ness of partial clone, 2020-01-30) returns 0 without closing it. receive-pack uses err_fd as the write end of an async sideband muxer's pipe, and the muxer thread waits for EOF. The same omission has caused deadlocks there twice before: 49ecfa13f (receive-pack: close sideband fd on early pack errors, 2013-04-19) and 6cdad1f13 (receive-pack: fix deadlock when we cannot create tmpdir, 2017-03-07). Signed-off-by: Ethan Dickson <ethanndickson@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-16trailer: change strbuf in-place in unfold_value()René Scharfe1-10/+5
Avoid an allocation by doing s/\n\s*/ /g (replacing NL and any following whitespace with a SP) right in the strbuf instead of copying the result to a temporary one and swapping them in the end. We can safely do that because the replacement is never longer than the original string. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-16commit: handle large commit messages in utf8 verificationJeff King1-16/+15
Running t4205 under UBSan with the EXPENSIVE prereq enabled triggers an error when we try to create a commit message that is over 2GB: commit.c:1574:6: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int' The problem is that find_invalid_utf8() is not prepared to handle large buffers, as it uses an "int" to represent buffer sizes and offsets. We can fix this with a few changes: 1. We'll take in "len" as a size_t (which is what the caller has anyway, since it's working with a strbuf). 2. We need to return a size_t to give the offset to the invalid utf8, but we also need a sentinel value for "no invalid value" (previously "-1"). Let's split these to return a bool for "found invalid utf8" and then pass back the offset as an out-parameter. We'll switch the function name to match the new semantics. 3. The caller in verify_utf8() uses a "long" to store buffer positions, which is a bit funny. This goes back to 08a94a145c (commit/commit-tree: correct latin1 to utf-8, 2012-06-28) and is perhaps trying to match our use of "unsigned long" for object sizes (though we don't care about it ever becoming negative here). This should be a size_t, too, as some platforms (like Windows) still use a 32-bit long on machines with 64-bit pointers. 4. The "bytes" field within find_invalid_utf() does not have range problems. It is the number of bytes the utf8 sequence claims to have, so is limited by how many bits can be set in a single 8-bit byte. However, if we leave it as an "int" then the compiler will complain about the sign mismatch when comparing it to "len". So let's make it unsigned, too. All of this is a little silly, of course, because 2GB text commit messages are clearly nonsense. So we might consider rejecting them outright, but it is easy enough to make these helper functions more robust in the meantime. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-16apply: plug leak on "patch too large" errorJeff King1-2/+4
In apply_patch(), we return immediately if read_patch_file() returns an error. Traditionally this was OK, since an error from strbuf_read() would restore the strbuf to its unallocated state. But since f1c0e3946e (apply: reject patches larger than ~1 GiB, 2022-10-25), we may also return an error if we successfully read the patch but it is too large. In this case we leak the strbuf contents when apply_patch() returns. You can see it in action by running t4141 under LSan with the EXPENSIVE prereq enabled. We can fix this in one of two places: 1. In read_patch_file(), we could release the buffer before returning the error, behaving more like a raw strbuf_read() call. 2. In apply_patch(), we can release the strbuf ourselves before returning. I picked the latter, since it future proofs us against read_patch_file() getting new error modes. We also have a cleanup label in that function already, so now our error handling at this spot matches the rest of the function (and all of the variables are initialized such that the rest of the cleanup is correctly a noop at this point). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-15t/unit-tests: add tests for the in-memory object sourcePatrick Steinhardt3-0/+315
While the in-memory object source is a full-fledged source, our code base only exercises parts of its functionality because we only use it in git-blame(1). Implement unit tests to verify that the yet-unused functionality of the backend works as expected. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-15odb: generic in-memory sourcePatrick Steinhardt2-5/+5
Make the in-memory source generic. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-15odb/source-inmemory: stub out remaining functionsPatrick Steinhardt1-0/+31
Stub out remaining functions that we either don't need or that are basically no-ops. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>