summaryrefslogtreecommitdiffstats
path: root/t
AgeCommit message (Collapse)AuthorLines
2026-05-17Merge branch 'rs/grep-column-only-match-fix'Junio C Hamano-3/+3
"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 Hamano-8/+106
"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 'en/ort-cached-rename-with-trivial-resolution'Junio C Hamano-0/+60
"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 Hamano-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 Hamano-6/+104
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-12Merge branch 'js/maintenance-fix-deadlock-on-win10'Junio C Hamano-1/+21
To help Windows 10 installations, avoid removing files whose contents are still mmap()'ed. * js/maintenance-fix-deadlock-on-win10: maintenance(geometric): do release the `.idx` files before repacking mingw: optionally use legacy (non-POSIX) delete semantics
2026-05-12Merge branch 'jc/t5551-fix-expensive'Junio C Hamano-0/+1
Test fix. * jc/t5551-fix-expensive: t5551: "GIT_TEST_LONG=Yes make test" is broken
2026-05-12Merge branch 'js/t5564-socks-use-short-path'Junio C Hamano-2/+9
Avoid hitting the pathname limit for socks proxy socket during the test.. * js/t5564-socks-use-short-path: t5564: use a short path for the SOCKS proxy socket
2026-05-11Merge branch 'jc/neuter-sideband-fixup'Junio C Hamano-0/+92
Try to resurrect and reboot a stalled "avoid sending risky escape sequences taken from sideband to the terminal" topic by Dscho. The plan is to keep it in 'next' long enough to see if anybody screams with the "everything dropped except for ANSI color escape sequences" default. * jc/neuter-sideband-fixup: sideband: drop 'default' configuration sideband: offer to configure sanitizing on a per-URL basis sideband: add options to allow more control sequences to be passed through sideband: do allow ANSI color sequences by default sideband: introduce an "escape hatch" to allow control characters sideband: mask control characters
2026-05-11Merge branch 'ps/test-set-e-clean'Junio C Hamano-69/+102
The test suite harness and many individual test scripts have been updated to work correctly when 'set -e' is in effect, which helps detect misspelled test commands. * ps/test-set-e-clean: t: detect errors outside of test cases t9902: fix use of `read` with `set -e` t6002: fix use of `expr` with `set -e` t1301: don't fail in case setfacl(1) doesn't exist or fails t0008: silence error in subshell when using `grep -v` t: prepare `test_when_finished ()`/`test_atexit()` for `set -e` t: prepare execution of potentially failing commands for `set -e` t: prepare conditional test execution for `set -e` t: prepare `git config --unset` calls for `set -e` t: prepare `stop_git_daemon ()` for `set -e` t: prepare `test_must_fail ()` for `set -e` t: prepare `test_match_signal ()` calls for `set -e`
2026-05-11Merge branch 'sb/userdiff-lisp-family'Junio C Hamano-4/+25
The userdiff driver for the Scheme language has been extended to cover other Lisp dialects. * sb/userdiff-lisp-family: userdiff: extend Scheme support to cover other Lisp dialects userdiff: tighten word-diff test case of the scheme driver
2026-05-11Merge branch 'ar/parallel-hooks'Junio C Hamano-7/+577
Hook scripts defined via the configuration system can now be configured to run in parallel. * ar/parallel-hooks: t1800: test SIGPIPE with parallel hooks hook: allow hook.jobs=-1 to use all available CPU cores hook: add hook.<event>.enabled switch hook: move is_known_hook() to hook.c for wider use hook: warn when hook.<friendly-name>.jobs is set hook: add per-event jobs config hook: add -j/--jobs option to git hook run hook: mark non-parallelizable hooks hook: allow pre-push parallel execution hook: allow parallel hook execution hook: parse the hook.jobs config config: add a repo_config_get_uint() helper repository: fix repo_init() memleak due to missing _clear()
2026-05-11Merge branch 'cc/promisor-auto-config-url'Junio C Hamano-23/+115
Promisor remote handling has been refactored and fixed in preparation for auto-configuration of advertised remotes. * cc/promisor-auto-config-url: t5710: use proper file:// URIs for absolute paths promisor-remote: remove the 'accepted' strvec promisor-remote: keep accepted promisor_info structs alive promisor-remote: refactor accept_from_server() promisor-remote: refactor has_control_char() promisor-remote: refactor should_accept_remote() control flow promisor-remote: reject empty name or URL in advertised remote promisor-remote: clarify that a remote is ignored promisor-remote: pass config entry to all_fields_match() directly promisor-remote: try accepted remotes before others in get_direct()
2026-05-11Merge branch 'dl/cache-tree-fully-valid-fix'Junio C Hamano-0/+8
The check that implements the logic to see if an in-core cache-tree is fully ready to write out a tree object was broken, which has been corrected. * dl/cache-tree-fully-valid-fix: cache-tree: fix inverted object existence check in cache_tree_fully_valid
2026-05-09t5551: "GIT_TEST_LONG=Yes make test" is brokenJunio C Hamano-0/+1
The "test_expect_success 'tag following always works over v0 http'" test in t5551 fails when it tries to run "git init tags", but this happens only when EXPENSIVE test is allowed to run. This is because the step tries to create a repository with "git init tags" but the EXPENSIVE test that runs way before it creates and leaves around a temporary file "tags". Have the EXPENSIVE test clean it up after itself. Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-08maintenance(geometric): do release the `.idx` files before repackingJohannes Schindelin-1/+21
As is done for all the other maintenance tasks, let's release the ODB also before starting the geometric repacking. That way, the `.idx` files won't be `mmap()`ed when they are to be deleted (which does not work on Windows because you cannot delete files on that platform as long as they are kept open by a process). This regression was introduced by 9bc151850c1c (builtin/maintenance: introduce "geometric-repack" task, 2025-10-24), but was only noticed once geometric repacking was made the default in 452b12c2e0fe (builtin/ maintenance: use "geometric" strategy by default, 2026-02-24). The fix recapitulates my work from df76ee7b77f0 (run-command: offer to close the object store before running, 2021-09-09) & friends. To guard against future regressions of this kind, add a check to `run_and_verify_geometric_pack()` in `t7900` that detects orphaned `.idx` files left behind after repacking. Contrary to interactive calls, the `git maintenance` call in that test case would _not_ block on Windows, asking whether to retry deleting that file, which is the reason why this bug was not caught earlier. Furthermore, since the default behavior of `DeleteFileW()` was changed at some point between Windows 10 Build 17134.1304 and Build 18363.657 to use POSIX semantics (see https://stackoverflow.com/a/60512798), the added orphaned-`.idx` check would be insufficient to catch this regression on modern Windows without emulating legacy delete semantics via `GIT_TEST_LEGACY_DELETE=1`. This fixes https://github.com/git-for-windows/git/issues/6210. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-29checkout -m: autostash when switching branchesHarald Nordgren-8/+82
When switching branches with "git checkout -m", the attempted merge of local modifications may cause conflicts with the changes made on the other branch, which the user may not want to (or may not be able to) resolve right now. Because there is no easy way to recover from this situation, we discouraged users from using "checkout -m" unless they are certain their changes are trivial and within their ability to resolve conflicts. Teach the -m flow to create a temporary stash before switching and reapply it after. On success, the stash is silently applied and the list of locally modified paths is shown, same as a successful "git checkout" without "-m". If reapplying causes conflicts, the stash is kept and the user is told they can resolve and run "git stash drop", or run "git reset --hard" and later "git stash pop" to recover their changes. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-29stash: add --label-ours, --label-theirs, --label-base for applyHarald Nordgren-0/+24
Allow callers of "git stash apply" to pass custom labels for conflict markers instead of the default "Updated upstream" and "Stashed changes". Document the new options and add a test. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-29t5564: use a short path for the SOCKS proxy socketJohannes Schindelin-2/+9
The SOCKS proxy test introduced in 0ca365c2ed4 (http: do not ignore proxy path, 2024-08-02) creates a Unix domain socket in `$TRASH_DIRECTORY`. When the trash directory path is long (e.g. when running from a deeply nested worktree), the socket path can exceed the 108-character limit for `struct sockaddr_un.sun_path` on Linux, causing the test to fail with "Path length ... is longer than maximum supported length (108)". We cannot work around this using the chdir trick our own socket code employs, because both sides of the connection are outside our control: the socket is created by socks4-proxy.pl via Perl's IO::Socket::UNIX, and the client side is libcurl. Use `mktemp -d` to create a unique temporary directory with a short path, and place the socket inside it. This avoids collisions between concurrent test runs (e.g. `--stress`) and tmpdir-race vulnerabilities that a static `/tmp` path would be susceptible to. Helped-by: Jeff King <peff@peff.net> 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-04-25grep: fix --column --only-match for 2nd and later matchesRené Scharfe-3/+3
"git grep --column --only-match" shows the 1-based column number of the first match on each line, but confusing numbers for further matches. Example: $ echo 123456789012345678901234567890 >file $ for d in 1 2 3 4 5 6 7 8 9 0 do git grep --no-index --column --only-matching $d file | awk -v FS=: -v l=$d: '{l = l sprintf("%3s", $2)} END {print l}' done 1: 1 2 12 2: 2 4 14 3: 3 6 16 4: 4 8 18 5: 5 10 20 6: 6 12 22 7: 7 14 24 8: 8 16 26 9: 9 18 28 0: 10 20 30 Report the column number of each match instead: $ for d in 1 2 3 4 5 6 7 8 9 0 do ./git grep --no-index --column --only-matching $d file | awk -v FS=: -v l=$d: '{l = l sprintf("%3s", $2)} END {print l}' done 1: 1 11 21 2: 2 12 22 3: 3 13 23 4: 4 14 24 5: 5 15 25 6: 6 16 26 7: 7 17 27 8: 8 18 28 9: 9 19 29 0: 10 20 30 We need to adjust the test in t7810 as well. The file it uses has the following five lines; I add a line highlighting the matches and a ruler at the bottom here, to make it easier to see that the second "mmap" indeed starts at column 14: foo mmap bar foo_mmap bar foo_mmap bar mmap foo mmap bar_mmap foo_mmap bar mmap baz ==== ==== 123456789 123456789 1 Reported-by: Brandon Chinn <brandonchinn178@gmail.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22merge-ort: handle cached rename & trivial resolution interaction betterElijah Newren-0/+60
Back in commit a562d90a350d (merge-ort: fix failing merges in special corner case, 2025-11-03), we hit a rename assertion due to a trivial directory resolution affecting the parent of a cached rename. Since the path didn't need to be considered, we side-stepped it with if (!newinfo) continue; in process_renames(). We have since run into a case in production where a trivial resolution of a file affects the direct target of a cached rename rather than a parent directory of it. Add a testcase demonstrating this additional case. Now, if we were to follow the lead of commit a562d90a350d, we could resolve this alternate case with an extra condition on the above if: if (!newinfo || newinfo->merged.clean) continue; However, if we had done that earlier, we would have made 979ee83e8a90 (merge-ort: fix corner case recursive submodule/directory conflict handling, 2025-12-29) harder to find and fix, and this particular position for this condition isn't actually at the root of the issue but downstream from it. Instead, let's rip out this if-check from a562d90a350d and put in an alternative that more directly addresses trivially resolved paths that happen to be cached renames or parent directories thereof, which is a better fix for the original testcase and which also solves the newly added testcase as well. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t: detect errors outside of test casesPatrick Steinhardt-0/+25
We have recently merged a patch series that had a simple misspelling of `test_expect_success`. Instead of making our tests fail though, this typo went completely undetected and all of our tests passed, which is of course unfortunate. This is a more general issue with our test suite: all commands that run outside of a specific test case can fail, and if we don't explicitly check for such failure then this failure will be silently ignored. Improve the status quo by enabling the errexit option so that any such unchecked failures will cause us to abort immediately. Note that for now, we only enable this option for Bash 5 and newer. This is because other shells have wildly different behaviour, and older versions of Bash (especially on macOS) are buggy. The list of enabled shells may be extended going forward. 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-04-22t9902: fix use of `read` with `set -e`Patrick Steinhardt-4/+2
In t9902 we're using the `read` builtin to read some values into a variable. This is done by using `-d ""`, which cause us to read until the end of the heredoc. As the read is terminated by EOF, the command will end up returning a non-zero error code. This hasn't been an issue until now as we didn't run with `set -e`, but that'll change in a subsequent commit. Prepare for this change by not using read at all, as we can simply store the multi-line value directly. Suggested-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t6002: fix use of `expr` with `set -e`Patrick Steinhardt-7/+10
In `test_bisection_diff ()` we use `expr` to perform some math. This command has some gotchas though in that it will only return success when the result is neither null nor zero. In some of our cases though it actually _is_ zero, and that will cause the expressions to fail once we enable `set -e`. Prepare for this change by instead using `$(( ))`, which doesn't have the same issue. While at it, modernize the function a tiny bit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t1301: don't fail in case setfacl(1) doesn't exist or failsPatrick Steinhardt-1/+1
In t1301 we're trying to remove any potentially-existing default ACLs that might exist on the transh directory by executing setfacl(1). According to 8ed0a740dd (t1301-shared-repo.sh: don't let a default ACL interfere with the test, 2008-10-16), this is done because we play around with permissions and umasks in this test suite. The setfacl(1) binary may not exist on some systems though, even though tests ultimately still pass. This doesn't matter currently, but will cause the test to fail once we start running with `set -e`. Silence such failures by ignoring failures here. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t0008: silence error in subshell when using `grep -v`Patrick Steinhardt-2/+2
In t0008 we use `grep -v` in a subshell, but expect that this command will sometimes not match anything. This would cause grep(1) to return an error code, but given that we don't run with `set -e` we swallow this error. We're about to enable `set -e`. Prepare for this by ignoring any errors. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t: prepare `test_when_finished ()`/`test_atexit()` for `set -e`Patrick Steinhardt-2/+2
Both `test_when_finished ()` and `test_atexit ()` build up a chain of cleanup commands by prepending each new command to the existing cleanup string. To preserve the exit code of the test body across cleanup execution, we append the following logic: } && (exit "$eval_ret"); eval_ret=$?; ... The intent of this is to run the cleanup block and then unconditionally restore `eval_ret`. The original behaviour of this is is: +------------------+---------+------------------------------------+ |test body │ cleanup │ old behaviour │ +------------------+---------+------------------------------------+ │pass (eval_ret=0) | pass │ && taken -> (exit 0) -> eval_ret=0 | +------------------+---------+------------------------------------+ │pass (eval_ret=0) | fail │ && not taken -> eval_ret=$? | +------------------+---------+------------------------------------+ │fail (eval_ret=1) | pass │ && taken -> (exit 1) -> eval_ret=1 | +------------------+---------+------------------------------------+ │fail (eval_ret=1) | fail | && not taken -> eval_ret=$? | +------------------+---------+------------------------------------+ This logic will start to fail once we enable `set -e`. When `$eval_ret` is non-zero, the subshell we create will fail, and with `set -e` we'll thus bail out without evaluating the logic after the semicolon. Fix this issue by instead using `|| eval_ret=\$?; ...`. Besides being a bit simpler, it also retains the original behaviour: +------------------+---------+------------------------------------+ |test body │ cleanup │ old behaviour │ +------------------+---------+------------------------------------+ │pass (eval_ret=0) | pass │ || not taken -> eval_ret unchanged | +------------------+---------+------------------------------------+ │pass (eval_ret=0) | fail │ || taken -> eval_ret=$? | +------------------+---------+------------------------------------+ │fail (eval_ret=1) | pass │ || not taken -> eval_ret unchanged | +------------------+---------+------------------------------------+ │fail (eval_ret=1) | fail | || taken -> eval_ret=$? | +------------------+---------+------------------------------------+ Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t: prepare execution of potentially failing commands for `set -e`Patrick Steinhardt-24/+24
Several of our tests verify whether a certain binary can be executed, potentially skipping tests in case we cannot, for example because the binary doesn't exist. In those cases we often run the binary outside of any conditionally. This will start to fail once we enable `set -e`, as that will cause us to bail out the test immediately. Improve these tests by executing them inside of a conditional instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t: prepare conditional test execution for `set -e`Patrick Steinhardt-16/+20
We have some test in our test suite where we use the pattern of `test ... && test_expect_succeess` to conditionally execute a test. The problem is that when we decide to not execute the test, we'll indeed skip the test, but the overall statement will also be unsuccessful. This will become a problem once we enable `set -e`. Prepare for this future by turning this into a proper conditional, which is also a bit easier to read overall. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t: prepare `git config --unset` calls for `set -e`Patrick Steinhardt-5/+5
We have a couple of calls to `git config --unset` that ultimately end up as no-ops as the configuration variables aren't set (anymore) in the first place. These calls are mostly intended to recover unconditionally from tests that may have executed only partially, but they'll ultimately fail during a normal test run. This hasn't been a problem until now as we aren't running tests with `set -e`. This is about to change though, so let's silence the case where we cannot unset the config keys. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t: prepare `stop_git_daemon ()` for `set -e`Patrick Steinhardt-3/+5
We have a couple of calls to `stop_git_daemon ()` outside of specific test cases that will kill a backgrounded git-daemon(1) process and expect the process with a specific error code. While these function calls do end up killing git-daemon(1), the error handling we have in those contexts is basically ineffective. So while we expect the process to exit with a specific error code, we will just continue with any error in case it doesn't. This will change once we enable `set -e` in a subsequent commit. There's two issues though that will make this _always_ fail: - Our call to `wait` is expected to fail, but because it's not part of a condition it will cause us to bail out immediately with `set -e`. - We try to kill git-daemon(1) a second time via the pidfile. We can generally expect that this is the same PID though as we had in the "GIT_DAEMON_PID" environment variable, and thus it's more likely than not that we have already killed it, and the call to kill will fail. Prepare for this change by handling the failure of `wait` with `||` and by silencing failures of the second call to `kill`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t: prepare `test_must_fail ()` for `set -e`Patrick Steinhardt-2/+3
The helper function `test_must_fail ()` executes a specific Git command that may or may not fail in a specific way. This is done by executing the command in question and then comparing its exit code against a set of conditions. This works, but once we run our test suite with `set -e` we may bail out of `test_must_fail ()` early in case the command actually fails, even though we expect it to fail. Prepare for this change by handling the failed case with `||`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22t: prepare `test_match_signal ()` calls for `set -e`Patrick Steinhardt-3/+3
We have a couple of calls to `test_match_signal ()` where we execute a Git command and expect it to die with a specific signal. These calls will essentially execute the process in a subshell via `foo; echo $?`, but as we expect `foo` to fail this will cause the overall subshell to fail once we `set -e`. Fix this issue by using `foo && echo 0 || echo $?` instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-21t7004: avoid subshells to capture git exit codesSiddharth Shrimali-8/+18
Several tests in t7004 use the 'test$(git ...) = ...' or the '! (git ...)' subshell pattern. This swallows git's exit code. If git crashes (e.g. segmentation fault) the crash would go undetected, and the test would fail due to a mismatch or an inverted exit code. Modernize these tests by directly writing output to files(actual) and verifying them with 'test_cmp' or 'test_grep'. Replace subshell negations with 'test_must_fail'. This way, if git crashes, the test fails immediately and clearly instead of hiding the error behind a string mismatch. Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-21t7004: dynamically grab expected state in testsSiddharth Shrimali-9/+2
The tests for 'Multiple -l or --list options' and 'trying to delete tags without params', hardcodes that exactly one or two specific tags ('myhead', 'mytag') exist in the repository. If other tests are added, modified, or removed earlier in the script, this expected global state will change, resulting in these tests to fail for completely unrelated reasons. Instead of hardcoding the expected tags, dynamically grab the state of the repository before running the commands under test ('git tag -l' and 'git tag -d'), and verify that the output matches or remains unchanged afterward. This keeps the tests independent from the script's overall state. Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-21t7004: drop hardcoded tag count for state verificationSiddharth Shrimali-4/+3
The test 'trying to create a tag with a non-valid name should fail', checked that exactly one tag existed in the repository before and after attempting to create invalid tags. As pointed out by Junio, this makes the test brittle by relying on a specific global tag count. If future tests are added or removed before this test, the expected state changes and this test would break for completely unrelated reasons. Modernize the test by taking a snapshot of the existing tags before the failure attempts and comparing it to a snapshot taken after. This provides a "belt-and-suspenders" approach: we verify that 'git tag' both exits with the expected error code and leaves the repository state untouched, without being brittle to the specific number of tags present. This replaces the hardcoded 'test_line_count = 1' checks with 'test_cmp' to ensure the tag list remains identical. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-16Merge branch 'jk/midx-write-v1-by-default'Junio C Hamano-1/+1
As writing version 2 MIDX files by default breaks older versions of Git and its reimplementations, use V2 only when necessary. * jk/midx-write-v1-by-default: MIDX: revert the default version to v1
2026-04-16MIDX: revert the default version to v1Jeff King-1/+1
We introduced midx version 2 in b2ec8e90c2 (midx: do not require packs to be sorted in lexicographic order, 2026-02-24) and now write it by default. The rationale was that older versions should ignore the v2 midx and fall back to using the packs (just like we do for other midx errors). Unfortunately this is not the case, as we have a hard die() when we see an unknown midx version. As a result, writing a midx with Git 2.54-rc2 puts the repository into a state that is unusable with Git 2.53. And this midx write may happen behind the scenes as part of normal operations, like fetch. Let's switch back to writing v1 by default to avoid regressing the case where multiple versions of Git are used on the same repository. There is one gotcha, though: the v2 format is required for some new features, like midx compaction, and running "git multi-pack-index compact" will complain when asked to write a v1 index. The user must set midx.version to "2" to make the feature work. So instead of always using v1, we'll base the default on whether the requested feature requires v2. That does mean that running midx compaction will create a repository that can't be read by older versions of Git. But we never do that by default; only people experimenting with the new feature will be affected. We have to adjust the test expectation in t5319, since it will now generate v1 files. And our "auto-select v2" is covered by the tests in t5335, which continue to check that compaction works without having to set midx.version manually (and also explicitly check that asking for v1 with compaction reports the problem). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-15backfill: default to grabbing edge blobs tooElijah Newren-6/+104
Commit 302aff09223f (backfill: accept revision arguments, 2026-03-26) added support for accepting revision arguments to backfill. This allows users to do things like git backfill --remotes ^v2.3.0 and then run many commands without triggering on-demand downloads of blobs. However, if they have topics based on v2.3.0, they will likely still trigger on-demand downloads. Consider, for example, the command git log -p v2.3.0..topic This would still trigger on-demand blob loadings after the backfill command above, because the commit(s) with A as a parent will need to diff against the blobs in A. In fact, multiple commands need blobs from the lower boundary of the revision range: * git log -p A..B # After backfill A..B * git replay --onto TARGET A..B # After backfill TARGET^! A..B * git checkout A && git merge B # After backfill A...B Add an extra --[no-]include-edges flag to allow grabbing blobs from edge commits. Since the point of backfill is to prevent on-demand blob loading and these are common commands, default to --include-edges. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-15userdiff: extend Scheme support to cover other Lisp dialectsScott L. Burson-3/+21
Common Lisp has top-level forms, such as 'defun' and 'defmacro', that are not matched by the current Scheme pattern. Also, it is more common in CL, when defining user macros intended as top-level forms, to prefix their names with "def" instead of "define"; such forms are also not matched. And some top-level forms don't even begin with "def". On the other hand, it is an established formatting convention in the Lisp community that only top-level forms start at the left margin. So matching any unindented line starting with an open parenthesis is an acceptable heuristic; false positives will be rare. However, there are also cases where notionally top-level forms are grouped together within some containing form. At least in the Common Lisp community, it is conventional to indent these by two spaces, or sometimes one. But matching just an open parenthesis indented by two spaces would be too broad; so the pattern added by this commit requires an indented form to start with "(def". It is believed that this strikes a good balance between potential false positives and false negatives. Signed-off-by: Scott L. Burson <Scott@sympoiesis.com> Acked-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-15userdiff: tighten word-diff test case of the scheme driverJohannes Sixt-3/+6
The scheme driver separates identifiers only at parentheses of all sorts and whitespace, except that vertical bars act as brackets that enclose an identifier. The test case attempts to demonstrate the vertical bars with a change from 'some-text' to '|a greeting|'. However, this misses the goal because the same word coloring would be applied if '|a greeting|' were parsed as two words. Have an identifier between vertical bars with a space in both the pre- and the post-image and change only one side of the space to show that the single word exists between the vertical bars. Also add cases that change parentheses of all kinds in a sequence of parentheses to show that they are their own word each. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Scott L. Burson <Scott@sympoiesis.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10t1800: test SIGPIPE with parallel hooksJeff King-0/+38
We recently fixed a bug in commit 2226ffaacd (run_processes_parallel(): fix order of sigpipe handling, 2026-04-08) where a hook that caused us to get SIGPIPE would accidentally trigger the run_processes_parallel() cleanup handler killing the child processes. For a single hook, this meant killing the already-exited hook. This case was triggered by our tests, but was only a problem on some platforms. But if you have multiple hooks running in parallel, this causes a problem everywhere, since one hook failing to read its input would take down all hooks. Now that we have parallel hook support, we can add a test for this case. It should pass already, due to the existing fix. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10hook: allow hook.jobs=-1 to use all available CPU coresAdrian Ratiu-0/+49
Allow -1 as a value for hook.jobs, hook.<event>.jobs, and the -j CLI flag to mean "use as many jobs as there are CPU cores", matching the convention used by fetch.parallel and other Git subsystems. The value is resolved to online_cpus() at parse time so the rest of the code always works with a positive resolved count. Other non-positive values (0, -2, etc) are rejected with a warning (config) or die (CLI). Suggested-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10hook: add hook.<event>.enabled switchAdrian Ratiu-0/+83
Add a hook.<event>.enabled config key that disables all hooks for a given event, when set to false, acting as a high-level switch above the existing per-hook hook.<friendly-name>.enabled. Event-disabled hooks are shown in "git hook list" with an "event-disabled" tab-separated prefix before the name: $ git hook list test-hook event-disabled hook-1 event-disabled hook-2 With --show-scope: $ git hook list --show-scope test-hook local event-disabled hook-1 When a hook is both per-hook disabled and event-disabled, only "event-disabled" is shown: the event-level switch is the more relevant piece of information, and the per-hook "disabled" status will surface once the event is re-enabled. Using an event name as a friendly-name (e.g. hook.<event>.enabled) can cause ambiguity, so a fatal error is issued when using a known event name and a warning is issued for unknown event name, since a collision cannot be detected with certainty for unknown events. Suggested-by: Patrick Steinhardt <ps@pks.im> Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10hook: warn when hook.<friendly-name>.jobs is setAdrian Ratiu-0/+30
Issue a warning when the user confuses the hook process and event namespaces by setting hook.<friendly-name>.jobs. Detect this by checking whether the name carrying .jobs also has .command, .event, or .parallel configured. Extract is_friendly_name() as a helper for this check, to be reused by future per-event config handling. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10hook: add per-event jobs configAdrian Ratiu-0/+59
Add a hook.<event>.jobs count config that allows users to override the global hook.jobs setting for specific hook events. This allows finer-grained control over parallelism on a per-event basis. For example, to run `post-receive` hooks with up to 4 parallel jobs while keeping other events at their global default: [hook] post-receive.jobs = 4 Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10hook: add -j/--jobs option to git hook runEmily Shaffer-7/+128
Expose the parallel job count as a command-line flag so callers can request parallelism without relying only on the hook.jobs config. Add tests covering serial/parallel execution and TTY behaviour under -j1 vs -jN. Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10hook: mark non-parallelizable hooksEmily Shaffer-0/+16
Several hooks are known to be inherently non-parallelizable, so initialize them with RUN_HOOKS_OPT_INIT_FORCE_SERIAL. This pins jobs=1 and overrides any hook.jobs or runtime -j flags. These hooks are: applypatch-msg, pre-commit, prepare-commit-msg, commit-msg, post-commit, post-checkout, and push-to-checkout. Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10hook: allow pre-push parallel executionAdrian Ratiu-0/+32
pre-push is the only hook that keeps stdout and stderr separate (for backwards compatibility with git-lfs and potentially other users). This prevents parallelizing it because run-command needs stdout_to_stderr=1 to buffer and de-interleave parallel outputs. Since we now default to jobs=1, backwards compatibility is maintained without needing any extension or extra config: when no parallelism is requested, pre-push behaves exactly as before. When the user explicitly opts into parallelism via hook.jobs > 1, hook.<event>.jobs > 1, or -jN, they accept the changed output behavior. Document this and let get_hook_jobs() set stdout_to_stderr=1 automatically when jobs > 1, removing the need for any extension infrastructure. Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10hook: allow parallel hook executionEmily Shaffer-0/+142
Hooks always run in sequential order due to the hardcoded jobs == 1 passed to run_process_parallel(). Remove that hardcoding to allow users to run hooks in parallel (opt-in). Users need to decide which hooks to run in parallel, by specifying "parallel = true" in the config, because Git cannot know if their specific hooks are safe to run or not in parallel (for e.g. two hooks might write to the same file or call the same program). Some hooks are unsafe to run in parallel by design: these will marked in the next commit using RUN_HOOKS_OPT_INIT_FORCE_SERIAL. The hook.jobs config specifies the default number of jobs applied to all hooks which have parallelism enabled. Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>