From 9f3a11508719a244fa52d5418bfd29847a272211 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Wed, 26 Nov 2025 14:33:37 +0000 Subject: [PATCH 1/6] replay: do not copy "gpgsign-sha256" header When "git replay" replays a commit it copies the extended headers across from the original commit. However, if the original commit was signed, we do not want to copy the header associated with the signature is it wont be valid for the new commit. The code already knows to avoid coping the "gpgsig" header but does not know to avoid copying the "gpgsig-sha256" header. Add that header to the list of exclusions to match what "git commit --amend" does. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- builtin/replay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/replay.c b/builtin/replay.c index 6172c8aacc9873..d12e4d548727d6 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -67,7 +67,7 @@ static struct commit *create_commit(struct repository *repo, const char *message = repo_logmsg_reencode(repo, based_on, NULL, out_enc); const char *orig_message = NULL; - const char *exclude_gpgsig[] = { "gpgsig", NULL }; + const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL }; commit_list_insert(parent, &parents); extra = read_commit_extra_headers(based_on, exclude_gpgsig); From bf25fca31c5a923598ce8461034a992920e3625b Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Fri, 28 Nov 2025 01:21:05 +0000 Subject: [PATCH 2/6] t0614: use numerical comparison with test_line_count In this comparison, we want to know whether the number of lines is greater than 1. Our test_line_count function passes the first argument as the comparison operator to test, so what we want is a numerical comparison, not a string comparison. While this does not produce a functional problem now, it could very well if we expected two or more items, in which case the value "10" would not match when it should. Furthermore, the "<" and ">" comparisons are new in POSIX 1003.1-2024 and we don't want to require such a new version of POSIX since many popular and supported operating systems were released before that version of POSIX was released. Finally, zsh's builtin test operator does not like the greater-than sign in "test", since it is only supported in the double-bracket extension. This has been reported and will be addressed in a future version, but since our code is also technically incorrect, as well as not very compatible, let's fix it by using a numeric comparison. Signed-off-by: brian m. carlson Signed-off-by: Junio C Hamano --- t/t0614-reftable-fsck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/t0614-reftable-fsck.sh b/t/t0614-reftable-fsck.sh index 85cc47d67e13bf..677eb9143c9de4 100755 --- a/t/t0614-reftable-fsck.sh +++ b/t/t0614-reftable-fsck.sh @@ -20,7 +20,7 @@ test_expect_success "no errors reported on a well formed repository" ' done && # The repository should end up with multiple tables. - test_line_count ">" 1 .git/reftable/tables.list && + test_line_count -gt 1 .git/reftable/tables.list && git refs verify 2>err && test_must_be_empty err From a92f243a94e6810394fb01d517726487252007f0 Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Fri, 28 Nov 2025 01:21:06 +0000 Subject: [PATCH 3/6] t5564: fix test hang under zsh's sh mode This test starts a SOCKS server in Perl in the background and then kills it after the tests are done. However, when using zsh (in sh mode) in the tests, the start_socks function hangs until the background process is killed. Note that this does not reproduce in a simple shell script, so there is likely some interaction between job handling, our heavy use of eval in the test framework, and possibly other complexities of our test framework. What is clear, however, is that switching from a compound statement to a subshell fixes the problem entirely and the test passes with no problem, so do that. Signed-off-by: brian m. carlson Signed-off-by: Junio C Hamano --- t/t5564-http-proxy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/t5564-http-proxy.sh b/t/t5564-http-proxy.sh index c3903faf2d3e6f..3bcbdef409b25f 100755 --- a/t/t5564-http-proxy.sh +++ b/t/t5564-http-proxy.sh @@ -40,10 +40,10 @@ test_expect_success 'clone can prompt for proxy password' ' start_socks() { mkfifo socks_output && - { + ( "$PERL_PATH" "$TEST_DIRECTORY/socks4-proxy.pl" "$1" >socks_output & echo $! > "$TRASH_DIRECTORY/socks.pid" - } && + ) && read line Date: Thu, 27 Nov 2025 02:16:06 +0000 Subject: [PATCH 4/6] xdiff: optimize patience diff's LCS search The find_longest_common_sequence() function in patience diff is inefficient as it calls binary_search() for every unique line it encounters when deciding where to put it in the sequence. From instrumentation (using xctrace) on popular repositories, binary_search() takes up 50-60% of the run time within patience_diff() when performing a diff. To optimize this, add a boundary condition check before binary_search() is called to see if the encountered unique line is located after the entire currently tracked longest subsequence. If so, skip the unnecessary binary search and simply append the entry to the end of sequence. Given that most files compared in a diff are usually quite similar to each other, this condition is very common, and should be hit much more frequently than the binary search. Below are some end-to-end performance results by timing `git log --shortstat --oneline -500 --patience` on different repositories with the old and new code. Generally speaking this seems to give at least 8-10% speed up. The "binary search hit %" column describes how often the algorithm enters the binary search path instead of the new faster path. Even in the WebKit case we can see that it's quite rare (1.46%). | Repo | Speed difference | binary search hit % | |----------|------------------|---------------------| | vim | 1.27x | 0.01% | | pytorch | 1.16x | 0.02% | | cpython | 1.14x | 0.06% | | ripgrep | 1.14x | 0.03% | | git | 1.13x | 0.12% | | vscode | 1.09x | 0.10% | | WebKit | 1.08x | 1.46% | The benchmarks were done using hyperfine, on an Apple M1 Max laptop, with git compiled with `-O3 -flto`. Signed-off-by: Yee Cheng Chin Signed-off-by: Junio C Hamano --- xdiff/xpatience.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xdiff/xpatience.c b/xdiff/xpatience.c index 77dc411d1937ab..d4094e6acf8810 100644 --- a/xdiff/xpatience.c +++ b/xdiff/xpatience.c @@ -211,7 +211,10 @@ static int find_longest_common_sequence(struct hashmap *map, struct entry **res) for (entry = map->first; entry; entry = entry->next) { if (!entry->line2 || entry->line2 == NON_UNIQUE) continue; - i = binary_search(sequence, longest, entry); + if (longest == 0 || entry->line2 > sequence[longest - 1]->line2) + i = longest - 1; + else + i = binary_search(sequence, longest, entry); entry->previous = i < 0 ? NULL : sequence[i]; ++i; if (i <= anchor_i) From 136f86abc052ef6186d9985fc26833ffc0484888 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Sat, 29 Nov 2025 04:44:24 +0000 Subject: [PATCH 5/6] Documentation/git-replay.adoc: fix errors around revision range There was significant confusion in the git-replay manual about what constitutes a revision range. As noted in f302c1e4aa09 (revisions(7): clarify that most commands take a single revision range, 2021-05-18): Commands that are specifically designed to take two distinct ranges (e.g. "git range-diff R1 R2" to compare two ranges) do exist, but they are exceptions. Unless otherwise noted, all "git" commands that operate on a set of commits work on a single revision range. `git replay` is not an exception, but a few places in the manual were written as though it were. These appear to have come in revisions to the original series, between v3->v4 (see https://lore.kernel.org/git/CAP8UFD3bpLrVW97DH7j=V9H2GsTSAkksC9L3QujQERFk_kLnZA@mail.gmail.com/ , "More than one can be passed") and between v6->v7 (https://lore.kernel.org/git/20231115143327.2441397-1-christian.couder@gmail.com/, "Takes ranges of commits"), and I missed both of these revisions when reviewing. Fix them now. There was also a reference to the "Commit Limiting options below", but this page has no such section of options; strike the misleading reference. It is worth noting that we are documenting existing behavior, rather than optimal behavior. Junio has multiple times suggested introducing alternative ways to walk revisions and use them in `git replay --advance`, e.g. at * https://lore.kernel.org/git/xmqqy1mqo6kv.fsf@gitster.g/ * https://lore.kernel.org/git/xmqq8rb3is8c.fsf@gitster.g/ * https://lore.kernel.org/git/xmqqtsydj2zk.fsf@gitster.g/ (item (2)) If/when we introduce some new revision walking flag that implements one of these alternate types of revision walks, we can update the --advance option and this manual appropriately. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- Documentation/git-replay.adoc | 13 ++++++------- builtin/replay.c | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Documentation/git-replay.adoc b/Documentation/git-replay.adoc index dcb26e8a8e88ca..d03235cca0c668 100644 --- a/Documentation/git-replay.adoc +++ b/Documentation/git-replay.adoc @@ -9,12 +9,12 @@ git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos t SYNOPSIS -------- [verse] -(EXPERIMENTAL!) 'git replay' ([--contained] --onto | --advance ) [--ref-action[=]] ... +(EXPERIMENTAL!) 'git replay' ([--contained] --onto | --advance ) [--ref-action[=]] DESCRIPTION ----------- -Takes ranges of commits and replays them onto a new location. Leaves +Takes a range of commits and replays them onto a new location. Leaves the working tree and the index untouched. By default, updates the relevant references using an atomic transaction (all refs update or none). Use `--ref-action=print` to avoid automatic ref updates and @@ -55,11 +55,10 @@ which uses the target only as a starting point without updating it. The default mode can be configured via the `replay.refAction` configuration variable. :: - Range of commits to replay. More than one can - be passed, but in `--advance ` mode, they should have - a single tip, so that it's clear where should point - to. See "Specifying Ranges" in linkgit:git-rev-parse[1] and the - "Commit Limiting" options below. + Range of commits to replay; see "Specifying Ranges" in + linkgit:git-rev-parse[1]. In `--advance ` mode, the + range should have a single tip, so that it's clear to which tip the + advanced should point. include::rev-list-options.adoc[] diff --git a/builtin/replay.c b/builtin/replay.c index 6606a2c94bc671..e6d6d2823969e5 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -366,7 +366,7 @@ int cmd_replay(int argc, const char *const replay_usage[] = { N_("(EXPERIMENTAL!) git replay " "([--contained] --onto | --advance ) " - "[--ref-action[=]] ..."), + "[--ref-action[=]] "), NULL }; struct option replay_options[] = { From e85ae279b0d58edc2f4c3fd5ac391b51e1223985 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 9 Dec 2025 07:53:51 +0900 Subject: [PATCH 6/6] The seventh batch Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.53.0.adoc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Documentation/RelNotes/2.53.0.adoc b/Documentation/RelNotes/2.53.0.adoc index 9e896bd4244389..38cbd2186e8172 100644 --- a/Documentation/RelNotes/2.53.0.adoc +++ b/Documentation/RelNotes/2.53.0.adoc @@ -23,6 +23,9 @@ UI, Workflows & Features * "git fast-import" learns "--strip-if-invalid" option to drop invalid cryptographic signature from objects. + * The use of "revision" (a connected set of commits) has been + clarified in the "git replay" documentation. + Performance, Internal Implementation, Development Support etc. -------------------------------------------------------------- @@ -135,6 +138,18 @@ Fixes since v2.52 have been corrected. (merge df963f0df4 rs/config-set-multi-error-message-fix later to maint). + * "git replay" forgot to omit the "gpgsig-sha256" extended header + from the resulting commit the same way it omits "gpgsig", which has + been corrected. + (merge 9f3a115087 pw/replay-exclude-gpgsig-fix later to maint). + + * A few tests have been updated to work under the shell compatible + mode of zsh. + (merge a92f243a94 bc/zsh-testsuite later to maint). + + * The way patience diff finds LCS has been optimized. + (merge c7e3b8085b yc/xdiff-patience-optim later to maint). + * Other code cleanup, docfix, build fix, etc. (merge 46207a54cc qj/doc-http-bad-want-response later to maint). (merge df90eccd93 kh/doc-commit-extra-references later to maint).