summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2026-07-10bisect: handle NULL commit in `bisect_successful()`Johannes Schindelin1-0/+5
When `lookup_commit_reference_by_name()` is called to find the first bad commit, the result is passed to `repo_format_commit_message()` immediately, which dereferences commit without checking for NULL. However, the commit could be NULL, even though in practice this is unlikely because `bisect_successful()` is only called after a successful bisect run has identified the bad commit, but the ref could still become dangling due to a concurrent gc or repository corruption. 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-10mailsplit: move NULL check before first use of file handleJohannes Schindelin1-3/+3
The `split_mbox()` function calls fileno(f) to check whether the input is a terminal, but the NULL check for f (from `fopen()`) does not happen until later. When the file cannot be opened, f is NULL, and `fileno(NULL)` is undefined behavior, typically crashing with a segmentation fault. Move the NULL check above the `isatty()`/`fileno()` call so the error path is taken before any use of the potentially-NULL handle. 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-10reftable/stack: guard against NULL list_file in stack_destroyJohannes Schindelin1-1/+2
When reftable_new_stack() fails partway through initialization (e.g., reftable_buf_addstr returns an OOM error before reftable_buf_detach assigns p->list_file), it jumps to the error path which calls reftable_stack_destroy(p). At that point, p->list_file is still NULL because the detach never happened. reftable_stack_destroy() passes st->list_file unconditionally to read_lines(), which calls open(filename, O_RDONLY). Passing NULL to open() is undefined behavior and will typically crash. Guard the read_lines() call with a NULL check on st->list_file. When list_file is NULL, there are no table files to clean up anyway, so skipping read_lines is the correct behavior. 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-10remote: guard `remote_tracking()` against NULL remoteJohannes Schindelin1-0/+2
The `remote_tracking()` function unconditionally dereferences `remote->fetch` without checking whether remote is NULL. In practice, this never happens because the only caller (`apply_cas()`) guards the calls to this function by checking the `use_tracking` and `use_tracking_for_rest` attributes. However, it requires quite involved reasoning to reach that conclusion, and is therefore fragile. Just return -1 ("no tracking ref") when there is no remote to work with. 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-10diff: handle NULL return from repo_get_commit_tree()Johannes Schindelin1-3/+7
The `repo_get_commit_tree()` function can return NULL when a commit's tree object is not available (e.g., the commit was parsed but its maybe_tree field is unset and the commit is not in the commit-graph). In cmd_diff(), the return value is immediately dereferenced via ->object without a NULL check, which would crash if the tree cannot be loaded. Add an explicit NULL check and die with a descriptive message. 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-10diffcore-break: guard against NULLed queue entries in merge loopJohannes Schindelin1-0/+2
The outer loop in `diffcore_merge_broken()` sets `q->queue[j]` to NULL when it merges a broken pair back together, and has a NULL check to skip such entries on subsequent iterations. The inner loop, however, lacks this guard: when it scans forward looking for a matching peer, it can encounter a slot that was NULLed by a previous outer-loop iteration and dereference it unconditionally. In practice this requires at least two broken pairs whose peers both survive rename/copy detection and appear later in the queue, which is rare but not impossible. Add the same `if (!pp) continue` guard to the inner loop. 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-09commit-graph: propagate topo_levels slab to all chain layersKristofer Karlsson2-2/+2
The topo_levels slab is only propagated to the topmost graph layer instead of all layers in the chain. Commits from lower layers appear to have no generation numbers, so the DFS re-walks the entire ancestry. Fix by making topo_levels visible to all layers, not just the first one. Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-09commit-graph: add trace2 instrumentation for generation DFSKristofer Karlsson2-0/+29
Count the number of steps taken in compute_reachable_generation_numbers() and expose it via trace2 to make it easier to detect performance regressions. Add a failing test for such a regression, introduced in 199d452758 (commit-graph: return the prepared commit graph from `prepare_commit_graph()`, 2025-09-04), where incremental commit-graph writes do not see existing generation numbers from lower graph layers and fall back to walking the full ancestry. Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-09Merge branch 'ps/odb-drop-whence' into ps/odb-for-each-object-filterJunio C Hamano14-69/+130
* ps/odb-drop-whence: odb: document object info fields odb: drop `whence` field from object info treewide: convert users of `whence` to the new source field odb: add `source` field to struct object_info_source odb: make backend-specific fields optional packfile: thread odb_source_packed through packed_object_info()
2026-07-09Merge branch 'ps/refs-writing-subcommands' into ps/refs-wo-the-repositoryJunio C Hamano7-8/+973
* ps/refs-writing-subcommands: builtin/refs: add "rename" subcommand builtin/refs: add "create" subcommand builtin/refs: add "update" subcommand builtin/refs: add "delete" subcommand builtin/refs: drop `the_repository`
2026-07-09mailmap: map Taylor Blau's work addressTaylor Blau1-0/+1
Signed-off-by: Taylor Blau <ttaylorr@openai.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-09t1410-reflog.sh: avoid suppressing git's exit code in pipelinesGatla Vishweshwar Reddy1-17/+9
Piping git commands directly to wc -l suppresses the exit code of git, hiding potential failures from the test suite. Use test_stdout_line_count instead, which handles exit code preservation internally while keeping the test logic clean and readable. Signed-off-by: Gatla Vishweshwar Reddy <gatlavishweshwarreddy26@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-08unpack-trees: avoid quadratic index scan in next_cache_entry()Henrique Ferreiro2-1/+35
Diffing the working tree against a commit with a pathspec can take time quadratic in the size of the index when the pathspec matches a subtree whose entries are the first entries of the index. Fix it by having next_cache_entry() record how far it scanned in cache_bottom, so repeated calls no longer rescan the growing prefix of already-unpacked entries. On a Chromium checkout (~500k index entries), git diff HEAD -- .agents/OWNERS took about 8 minutes before this change and 0.07 seconds after it. The same diff without the commit, without the pathspec, or with --cached was already instant. Add p0009-diff-pathspec.sh, which builds a 10,000-entry index whose first path lives in a subtree (100,000 entries under --long-tests), to guard against the regression. Comparing v2.55.0 with this change using GIT_TEST_LONG=t: Test v2.55.0 HEAD ------------------------------------------------------------------------ 0009.2: diff pathspec subtree 7.16(7.12+0.01) 0.02(0.01+0.00) -99.7% Signed-off-by: Henrique Ferreiro <hferreiro@igalia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-08bundle-uri: stop sending invalid bundle configurationJustin Tobler2-2/+29
When bundle-URI info is requested by the client, the server responds with all "bundle.*" config lines as key=value packet lines. On the client-side, the received bundle config packet lines are always expected to contain both a key and a value otherwise the client errors out during parsing. The server performs no validation of the read bundle configuration though which results in any misconfiguration on the server-side, such as bundle configuration with an empty value, being blindly sent to the client. To avoid having the server transmit invalid configuration to clients, only send bundle configuration that has non-empty values. This change makes bundle-URI information sent by the server syntactically correct, but semantically it still can be invalid. For example the server may end up sending `bundle.bundle-1.creationToken`, but be lacking a `bundle.bundle-1.uri` for that bundle. The `uri` is mandatory, thus the client cannot process this bundle and will error with the message: error: bundle 'bundle-1' has no uri Fixing this would require a more complex solution, because bundles need to be validated as a whole and not line-by-line. This is considered outside the scope of this change. Co-authored-by: Toon Claes <toon@iotcl.com> Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-08bundle-uri: drain remaining response on invalid bundle-uri linesToon Claes2-3/+41
On clone, when the client sends the `bundle-uri` command, the server might respond with invalid data. For example if it sends information about a bundle where the 'uri' is empty, it produces the following error: Cloning into 'foo'... error: bundle-uri: line has empty key or value error: error on bundle-uri response line 4: bundle.bundle-1.uri= error: could not retrieve server-advertised bundle-uri list This error is bubbled up to `transport_get_remote_bundle_uri()`, which is called by `cmd_clone()` in builtin/clone.c. Over here, the return value is ignored, so clone continues. Despite this, it still dies with this error: fatal: expected 'packfile' This happens because `get_remote_bundle_uri()` exited early, leaving some unprocessed packet data behind in the read buffer. This is misleading to the user, because it suggests a problem with the packfile exchange, when in reality it's caused by a misconfigured bundle-URI on the server-side. Fix this by continuing to read packets when an error was encountered, but without processing the remaining lines. This drains the protocol stream so no stale data is left behind and the caller can use it if they like. With this, clone now continues successfully if invalid bundle-URI data was sent by the server. This is intentional, because since the inception of `transport_get_remote_bundle_uri()` in 0cfde740f0 (clone: request the 'bundle-uri' command when available, 2022-12-22) the return value of that function is ignored in `cmd_clone()` so the clone can continue without bundles. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-08SubmittingPatches: document how to retract a topicJunio C Hamano1-0/+14
While this document outlines an idealized lifecycle where an author develops a patch, refines it with reviewer feedback, and successfully merges it into Git, reality is rarely so seamless. Sometimes, a topic must be abandoned. Doing so explicitly is far better than leaving it in limbo, especially since topics can always be resurrected later. Clearly state that we encourage contributors to retract any topic that does not pan out. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-08submodule--helper: accept '-i' shorthand for update --initDominique Martinet1-1/+1
commit 3ad0ba722744 ("git-submodule.sh: improve variables readability") made `git submodules update -i` pass `-i` as is to submodule--helper, but it fails with `error: unknown switch `i'` because the helper does not accept the short option. All other short options supported by git-submodule.sh are properly handle in the helper, so also add the alias for --init Fixes: 3ad0ba722744 ("git-submodule.sh: improve variables readability") Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07contrib: wire up osxkeychain in contrib/Makefile on macOSShardul Natu2-1/+15
When running "make test" with TEST_CONTRIB_TOO=yes (which is default in macOS CI workflows), $(MAKE) -C contrib/ test is invoked. However, contrib/Makefile only invoked tests for diff-highlight and subtree, meaning git-credential-osxkeychain was never built or verified during standard CI test runs. Add a "test" target to contrib/credential/osxkeychain/Makefile that depends on building git-credential-osxkeychain. Additionally, wire up credential/osxkeychain in contrib/Makefile under "all", "test", and "clean" whenever running on macOS (Darwin). This ensures that running "make test" or "make all" in contrib on macOS automatically builds and links git-credential-osxkeychain, preventing future build or symbol linking regressions from slipping through CI. Signed-off-by: Shardul Natu <snatu@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07Makefile: support universal macOS builds via RUST_TARGETSShardul Natu1-4/+35
On macOS, Universal Binaries contain native executable code for multiple architectures (such as Intel x86_64 and Apple Silicon arm64) bundled into a single file. This is standard practice for macOS distribution and CI packaging (such as internal distribution packages or tooling like Burrito/Homebrew), allowing a single build artifact to run natively across all Macs without Rosetta emulation or maintaining separate packages. When building Git C code for multiple architectures on macOS, the Apple toolchain (clang) natively supports universal builds via CFLAGS/LDFLAGS. When "-arch x86_64 -arch arm64" is passed, clang automatically compiles and links universal binaries for all C object files and executables out of the box. Cargo and rustc, however, do not support multiple "-arch" flags or emitting universal binaries in a single invocation. Instead, Cargo requires invoking each target triple independently (e.g., passing "--target x86_64-apple-darwin" and "--target aarch64-apple-darwin"). To bridge this gap when Rust is enabled: 1. Allow specifying space-separated target triples in RUST_TARGETS. 2. Introduce declarative pattern rules (target/%/...) to compile each target-specific library slice via Cargo. 3. On macOS, if multiple targets are specified, use "lipo" (part of the mandatory Xcode Command Line Tools) to combine the resulting static libraries into target/release/libgitcore.a. Once $(RUST_LIB) is compiled into a universal static archive, the standard C linker seamlessly links it with the C object files to produce universal Git executables. Signed-off-by: Shardul Natu <snatu@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07Makefile: add $(RUST_LIB) prerequisite to osxkeychainShardul Natu1-1/+6
When Rust is enabled, the git-credential-osxkeychain helper depends on Rust symbols compiled into $(RUST_LIB). While commit 522ea8ef7d ("osxkeychain: fix build with Rust") updated the linker command line to use $(LIBS), it omitted $(RUST_LIB) from the target prerequisite list. Without this prerequisite, running a parallel build ("make -j") from a clean working tree can fail because Make does not know to invoke Cargo to build libgitcore.a before linking git-credential-osxkeychain. Note that we depend explicitly on $(LIB_FILE) and $(RUST_LIB) rather than $(GITLIBS). Unlike standard Git builtins and programs like scalar (which define cmd_main() and rely on common-main.o to supply main()), git-credential-osxkeychain.c defines its own standalone int main(). If $(GITLIBS) were used, $(filter %.o,$^) in the link recipe would match both git-credential-osxkeychain.o and common-main.o, causing a duplicate symbol linking error for _main on macOS. Additionally, wrap the definitions of $(RUST_LIB) and the "rust" build target in "ifndef NO_RUST". This ensures that when NO_RUST=1 is specified, $(RUST_LIB) evaluates to empty, making the Rust dependency a clean no-op without needing intermediate variables. Signed-off-by: Shardul Natu <snatu@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07hash: check ctx->active flag in all wrapper functionsJeff King1-0/+10
It only makes sense to call git_hash_update(), etc, on a hash context that has been initialized but not yet finalized or discarded. This is an unlikely error to make, but it's easy for us to catch it and complain. It's especially important because it would quietly "work" for many hash backends (like sha1dc, which is just manipulating some bytes) but would cause undefined behavior with others (like OpenSSL, which puts the context onto the heap). Checking the flag lets us catch problems consistently on every build. Note that we can't do the same for git_hash_init(). Even though it would cause a leak to call it twice (without an intervening final/discard), the point of the function is that the contents of the struct are undefined before the call. But calling it twice is an even less likely error to make, so not covering it is OK. We leave git_hash_discard() alone, as its idempotent behavior is convenient for callers. We _could_ try to do something similar for git_hash_final(), allowing: git_hash_final(result, &ctx); git_hash_final(other_result, &ctx); but it does not make much sense. After the first final() call we have thrown away the state, so we cannot produce the same output. We could come up with some sensible output (the null hash, or the empty hash), but double-calls like this are more likely a bug, so our best bet is to complain loudly (whereas the current code produces either nonsense output or undefined behavior, depending on the backend). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07http: use idempotent git_hash_discard()Jeff King2-5/+1
Now that it is OK to call git_hash_discard() even after finalizing the hash, we no longer need the ctx_valid bool added by a2d8ea5a76 (http: discard hash in dumb-http http_object_request, 2026-07-02). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07csum-file: use idempotent git_hash_discard()Jeff King1-12/+5
Now that it is safe to call git_hash_discard() even after finalizing it, we can simplify our cleanup logic a bit. This is mostly undoing a few bits of 64337aecde (csum-file: always finalize or discard hash, 2026-07-02): - We no longer need a separate free_hashfile_memory() function for finalize_hashfile(). It can just call free_hashfile(), which will now discard (or not) the hash as appropriate. - When f->skip_hash is set, we don't need to discard; we can rely on free_hashfile() to do it. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07hash: make git_hash_discard() idempotentJeff King2-0/+7
You must always either finalize or discard a hash context to release any resources, but you must call only one such function. This creates extra work for some callers, since their cleanup code paths need to know whether they got there via their happy path (and the finalization happened) or due to an error (in which case they need to discard). Let's add an "active" flag that turns a redundant discard into a noop. That lets you safely do this: git_hash_init(&ctx, algo); ... if (some_error) goto out; ... git_hash_final(result, &ctx); out: git_hash_discard(&ctx); This should avoid future errors, and will also let us simplify a few existing callers (in future patches). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07hash: document function pointers and wrappersJeff King1-11/+32
We want people to use the git_hash_*() wrappers rather than the bare function pointers in the git_hash_algo struct. Let's document them rather than the bare pointers, and warn people away from the pointers. Coccinelle will eventually force the use of the wrappers, but it's helpful to lead readers in the right direction from the start. While we're here we can document a few other bits of wisdom I've turned up while working in this area: - You have to initialize the destination of a git_hash_clone(). This is something we may eventually change for efficiency, but we should definitely document the requirement for now. - You must eventually finalize or discard a hash, since some backends may allocate resources during initialization. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07hash: convert remaining direct function callsJeff King3-19/+72
The previous patch added a coccinelle rule to make sure callers always use git_hash_init() rather than direct function pointers from the algo struct. Let's do the same for the rest of the git_hash_*() wrappers. I split these out because they're a bit different: they implicitly use the algop pointer in the git_hash_ctx. So when we convert: -algo->update_fn(&ctx, buf, len); +git_hash_update(&ctx, buf, len); we drop the reference to algo entirely! But this is always going to be the right thing. If "algo" does not match what is in ctx.algop, then we'd already be invoking undefined behavior. So in addition to making it possible to add more logic to the git_hash_*() functions, we're avoiding the need to pass around the extra algo pointer and make sure that it matches what's in "ctx". The rest of the patch is the mechanical application of that coccinelle patch, plus a minor cleanup in test-synthesize.c to drop a now-unused function parameter (since we don't have to pass around the algo separately anymore). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07hash: use git_hash_init() consistentlyJeff King21-41/+50
We'd like to add more logic to git_hash_init(), but many callers skip it and call algop->init_fn() directly. Let's make sure we're consistently using the wrapper by adding a coccinelle rule. Besides the coccinelle file itself, this is a purely mechanical conversion based on the patch it generates. There should be no bare init_fn() calls left (except for the one in the wrapper). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07parse-options: exit 0 on -hbrian m. carlson37-71/+85
The standard philosophy for Unix software when a help option (such as --help) is specified is that the software should exit 0, printing the help output to standard output, since the standard output is for user-requested output and the program performed the requested task successfully. If the user specifies an incorrect option, then the help output should be printed to standard error (since the user has made a mistake) and it should exit unsuccessfully. Most of our commands currently exit 129 on receiving the -h option to print the short help, which does not line up with the standard philosophy above. Let's change that to exit 0 instead. This requires changes to a variety of tests which previously wanted the 129 exit code, so update them. Note that because git diff does its own option parsing, it still exits with 129, so update some of the tests to expect either exit status. Some commands also now pass with -h but not --help-all, so handle those cases differently for those commands. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07rev-parse: have --parseopt callers exit 0 on --helpbrian m. carlson5-6/+13
The standard philosophy for Unix software when a help option (such as --help) is specified is that the software should exit 0, printing the help output to standard output, since the standard output is for user-requested output and the program performed the requested task successfully. If the user specifies an incorrect option, then the help output should be printed to standard error (since the user has made a mistake) and it should exit unsuccessfully. git rev-parse --parseopt properly directs the output in both of these cases, but it currently exits 129 when it receives a --help or -h option on the command line, which causes its invoking script to do the same. This is not in line with the usual behavior and it causes scripts using this command to exit unsuccessfully on --help as well. Note that Git subcommands implemented using scripts, such as git submodule, don't have this problem because Git itself intercepts the --help option and runs man (or a similar tool), which then exits 0. However, this still affects the myriad scripts that use this functionality because Git is widespread and the --parseopt functionality is a good way to get sensible option parsing across shells in a portable way. Because git rev-parse --parseopt is intended to be eval'd by the shell, when help output is to be printed to standard output, Git actually prints a cat command with a heredoc since the standard output is being evaluated by the shell. Thus, to do the right thing, simply add an "exit 0" right after the end of the heredoc, which will cause the invoking program to exit successfully. The usual invocation recommended by the manual page is this: eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)" Thus, the fact that git rev-parse --parseopt still exits 129 in this case is irrelevant, since the "echo exit $?" will print "exit 129", but that will be after the "exit 0" printed by Git—and thus ignored, since the shell will have already exited successfully. Update the tests for this case. Note that we no longer need to delete only the first and last lines in some tests, so add a command to delete the end of the heredoc as well. We could do something clever with sed to delete all but the last two lines or switch to head and tail, but those would be more complicated and less readable, so just stick with the simple approach. In t1517, add three shell scripts to the failure case because they no longer return 129 as expected. In a future commit, we'll change the expected result to exit 0 and these will become successful again. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07parse-options: add a separate case for help output on errorbrian m. carlson5-4/+13
When we parse a command line option such as -h or --help, we currently exit 129, since that is the exit code when help output is printed. In a future commit, we'll change this to exit 0 instead, since we're doing what the user wanted successfully. However, there are some cases where we print help output because the user has provided ambiguous or invalid input, such as an ambiguous option, and we'll want to exit unsuccessfully there. Make this easier by defining a new return code, PARSE_OPT_HELP_ERROR, that can be used in this case, while reserving PARSE_OPT_HELP for those cases where the user has requested help directly. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07t1517: skip svn tests if svn is not installedbrian m. carlson1-0/+9
The svn tests currently assume that git-svn's option parsing will always fail the tests because it exits 0 on --help, not 129. However, in a future commit, we'll expect it to exit 0 and the tests will then need to be updated to succeed in some cases and fail in others. We therefore need to have t1517 determine whether the Subversion Perl modules are present, since if they are not, git-svn will die on start and then it needs to continue to expect failure. Add a stripped down version of the tests in t/lib-git-svn.sh as a prerequisite we can use here for our svn tests. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07Rust: fix description in Release Notes to 2.55Junio C Hamano1-2/+2
Finish incomplete sentence to say that we - build Git 2.55 by default with Rust, - but you can opt out and build 2.55 without Rust, - but Rust will become mandatory in Git 3.0 and later. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07sideband: allow ANSI SGR with colon-separated subfieldsMantas Mikulėnas1-1/+5
The SGR values used for 256-color formatting are officially defined to be a single field with :-separated subfields (e.g. "\e[1;38:5:XX;40m") despite the more common but kludgy use of separate values (which then become context-dependent and lead to misinterpretation by incompatible terminals). Signed-off-by: Mantas Mikulėnas <grawity@gmail.com> Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07Merge branch 'jk/hash-algo-leak-fixes' into jk/git-hash-cleanupsJunio C Hamano13-14/+100
* jk/hash-algo-leak-fixes: hash: add platform-specific discard functions hash: fix memory leak copying sha256 gcrypt handles http: discard hash in dumb-http http_object_request check_stream_oid(): discard hash on read error patch-id: discard hash when done csum-file: provide a function to release checkpoints csum-file: always finalize or discard hash hash: add discard primitive csum-file: drop discard_hashfile()
2026-07-07setup: mark `set_git_work_tree()` as file-localPatrick Steinhardt2-3/+1
In the preceding commit we have removed the last callers of `set_git_work_tree()` that is located outside of "setup.c". Remove its declaration and mark the function as file-local. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: pass worktree to `init_db()`Patrick Steinhardt4-30/+23
In the preceding commits we have refactored how we discover and set up repositories so that we cannot end up with partially-configured repos. Instead, we apply the gitdir, worktree and repository format in a single location, only. Initializing a new repository has the same antipattern though: while most of the information for the new repository is passed via parameters, the work tree is instead propagated by configuring the repository's work tree. Refactor the code so that we also pass the work tree as an explicit parameter. Like this, configuration fo the repository happens in a single spot, too, just as with repository discovery. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: drop redundant configuration of `startup_info->have_repository`Patrick Steinhardt1-3/+1
In `init_db()` we set `startup_info->have_repository` twice: once before reading and applying the repository format and once after. This is redundant though, as configuring the repository format does not rely on this variable at all. Remove the first such site. While at it, fix up formatting a bit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: make repository discovery self-containedPatrick Steinhardt1-18/+25
In the preceding commits we have introduced a separate repository discovery phase and refactored the logic so that we have two clear phases: 1. Repository discovery, which doesn't modify the repository itself at all. 2. Repository configuration, which takes the information we have discovered to set up the repository. Extract the first phase into a new function `repo_discover()` to further stress these two different phases. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: propagate prefix via repository discoveryPatrick Steinhardt1-56/+45
In the preceding commits we have started to propagate all information required for the configuration of the repository via a new `struct repo_discovery`. The only exception is the repository's prefix, which we still return via the return parameter. This is conceptually fine, but somewhat inconsistent. Refactor this to instead propagate the prefix via the repository discovery, too. While at it, drop a static variable in `repo_discover_bare_gitdir()`. We apply its value to the repository discovery anyway, so we don't have to keep it around afterwards anymore. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: drop static `cwd` variablePatrick Steinhardt1-2/+3
The current working directory is stored as part of a static strbuf variable. This variable had to have a lifetime longer than its containing function because the value we return typically points into that buffer. In the preceding commit we have moved the prefix into the repository though. Consequently, we can now return the repository's prefix instead of the local one and thus properly manage the lifecycle of this local variable. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: move prefix into repositoryPatrick Steinhardt9-16/+25
The repository prefix is currently stored in the startup info. This feels somewhat awkward though, as it is inherently a property of a given repository. Move the prefix into the repository accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: embed repository format in discoveryPatrick Steinhardt1-31/+29
All functions related to repository discovery receive both a `struct repository_discovery` and `struct repository_format` as input, and the expectation is that both will be populated. Refactor this so that the repository format is part of the discovery result. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: introduce explicit repository discoveryPatrick Steinhardt1-57/+98
When setting up the global repository we intermix repository discovery and repository configuration: we repeatedly call `set_git_work_tree()` and `apply_and_export_relative_gitdir()` until we're happy with the result. The result of this is then a partially-configured repository that we use for further setup. This process is quite hard to follow, as it's never quite clear which parts of the repository have been configured already and which haven't. Furthermore, it means that the repository configuration is distributed across many different places instead of having it neatly contained in a single location. Ultimately, this is the reason that we cannot use a central function like `repo_init()`. Refactor the logic so that we stop partially-configuring a repository and instead populate a new `struct repo_discovery`. This allow us to essentially split repository setup into two phases: - The first phase only figures out parameters required to configure the repository. - The second phase then takes these parameters and applies them to the repository. Like this, we'll never end up with a partially-configured repository and can eventually extend `repo_init()` to handle the full initialization for us. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: split up concerns of `setup_git_env_internal()`Patrick Steinhardt2-45/+48
The function `setup_git_env_internal()` does two completely unrelated things: - It configures the repository's gitdir and propagates environment variables into it. - It configures a couple of global parameters via environment variables. The function is called when we initialize the repository's path, but it's also called via `chdir_notify_register()` whenever we change the current working directory. While we indeed have to reconfigure the gitdir in case it's a relative path, it doesn't make sense to reapply the global environment variables. Split up concerns of this function along the above delineation. Handling of the global environment variables is moved into `init_git()`, as they can be considered part of our setup procedure. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: unify setup of shallow filePatrick Steinhardt4-10/+8
It is possible to configure an arbitrary "shallow" file via two mechanisms, and the respective logic to handle these is split across two locations: - Via the "GIT_SHALLOW_FILE" environment variable, which is handled in `setup_git_env_internal()`. - Via the global "--shallow-file=" command line option, which is handled in `handle_options()`. We can rather easily unify this logic by not configuring the shallow file in `handle_options()`, but instead overwriting the environment variable. The environment variable itself is then handled inside of `apply_repository_format()`, which is responsible for configuring a discovered Git directory. This new logic is similar in nature to how we handle the other global options already, all of which end up setting an environment variable. So for one this gives us more consistency. But more importantly, this change means that `the_repository` will not contain any relevant state anymore before we hit `apply_repository_format()` once we're at the end of this patch series. Consequently, it will become possible for us to completely discard `the_repository` and populate it anew. Note that on first sight, this change looks like it might change the precedence order. Before this change, we used to configure the shallow file in the arguments handler first, and then it looks like we override it via the environment variable. What's important to note though is the last parameter to `set_alternate_shallow_file()`, which tells us whether we want to overwrite a preexisting value, and when applying the value from the environment we tell it not to overwrite preexisting values. So in effect, the command line has precedence over the environment. After this change, we now overwrite preexisting environment variables when we see the argument, and consequently we keep the precedence order in tact. With this change though we don't need the final parameter anymore that tells `set_alternate_shallow_file()` whether or not to overwrite. We only have a single callsite for this function now, and that function is itself only ever called exactly once. Remove that parameter. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: mark bogus worktree in `apply_repository_format()`Patrick Steinhardt1-16/+21
When a repository is configured to have both "core.worktree" and "core.bare" we emit a warning and mark the worktree configuration as bogus so that the next call to `setup_work_tree()` will cause us to die. This allows us to still use the misconfigured repository, at least as long as we don't try to use its worktree. This condition is handled in `setup_explicit_git_dir()`. In a subsequent commit we'll refactor this function so that it doesn't receive a repo as input anymore though, and consequently we cannot set the "bogus" bit anymore. Move the logic into `apply_repository_format()` instead to prepare for this. While at it, fix up formatting a bit. Note that this change requires us to also explicitly unset the value of "core.worktree" in case we have the "GIT_WORK_TREE" environment variable set. This is because the environment variable overrides the repository's configuration, and we don't want to warn or die in case the work tree has been configured explicitly regardless of whether or not "core.bare" is set. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07setup: rename `check_repository_format_gently()`Patrick Steinhardt1-19/+19
The function `check_repository_format_gently()` receives a format as input. An unknowing reader may thus suspect that this function actually checks the passed-in format for consistency. While the function indeed checks the repository format, it actually serves two purposes: - It reads the repository's format and populates the passed-in format with that information. - It then indeed checks whether the format is consistent. Rename the function to `read_and_verify_repository_format()` to clarify its functionality. While at it, reorder the parameters so that the format comes first to better match other functions that pass around the format. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06t0213: skip ancestry tests under user-mode emulationJamie Magee1-3/+6
The tests added in 3c8c638df6 (t0213: add trace2 cmd_ancestry tests, 2026-02-13) expect the cmd_ancestry event to name "test-tool" and "git". On Linux those names come from the "comm" field of /proc/<pid>/stat. Under user-mode emulation (e.g. qemu-user) /proc reports the emulator ("qemu-riscv64") instead, so the event is still emitted, the TRACE2_ANCESTRY probe enables the tests, and tests 2-5 fail even though they pass on native riscv64. Require the probe to see "test-tool" in the ancestry of a test-tool spawned from test-tool, so the tests skip when the names are unreliable. Cc: Matthew John Cheetham <mjcheetham@outlook.com> Signed-off-by: Jamie Magee <jamie.magee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06Start Git 2.56 cycleJunio C Hamano3-2/+115
This time, do not forget to update GIT-VERSION-GEN to say 2.55.GIT Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06Merge branch 'sg/t3420-do-not-grep-in-missing-file'Junio C Hamano1-1/+1
A test checking interactions between git rebase --quit and autostash in t3420-rebase-autostash.sh has been corrected to use test_path_is_missing instead of ! grep on a file that shouldn't exist in the conflicted state. * sg/t3420-do-not-grep-in-missing-file: t3420-rebase-autostash: don't try to grep non-existing files