* Re: [PATCH v4 0/8] commit-reach: terminate merge-base walk when one side is exhausted
From: Kristofer Karlsson @ 2026-06-29 12:59 UTC (permalink / raw)
To: Derrick Stolee; +Cc: Kristofer Karlsson via GitGitGadget, git, Elijah Newren
In-Reply-To: <5ef694a3-9164-4ab4-8835-136439f6d267@gmail.com>
On Mon, 29 Jun 2026 at 14:40, Derrick Stolee <stolee@gmail.com> wrote:
>
> I agree with your reasoning, data-backed discovery, and the course of
> action to fix this. I'm happy that you're able to close the loop on
> this long-standing performance issue even with v1 generation numbers.
Sounds good, then I can continue with the approach of removing some code
(even though it will likely be a net addition in the end).
> > Do you see any cases I might be missing where removing the fallback
> > could cause problems?
> I don't see any other concerns here. You're right that if we were to
> have a different mode that changes the priority-queue ordering, then
> the side-exhaustion optimization cannot be trusted, but you will
> remove this possibility.
>
> It _may_ be worth mentioning this with a comment when initializing
> the queue order for the paint_queue, because the use of the queue
> requires topological ordering.
Yes my plan is to rewrite v5 in a few ways:
- update original documentation to note that infinite -> finite
generation does not always hold
- add a test (or more than one) for this problem
- don't introduce the bug at any point
- add a commit to replace the disabled optimization with
removal of the commit-date based ordering (+ doc update)
Thanks for helping with this,
Kristofer
^ permalink raw reply
* [PATCH 0/2] commit-reach: fix !FIND_ALL early exit with v1 commit graph
From: Kristofer Karlsson via GitGitGadget @ 2026-06-29 13:19 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Derrick Stolee, Kristofer Karlsson
Fixes a bug introduced by 93e5b1680e (commit-reach: early exit
paint_down_to_common for single merge-base, 2025-04-10) where git merge-base
can return the wrong result.
The bug requires all of the following to trigger:
1. A v1 commit graph (topological levels only, no corrected commit dates).
Generation v2 with corrected commit dates has been the default since
2021, so only repos that have not rewritten their commit graph in over
four years would be affected.
2. git merge-base without --all (the common case, but --all is unaffected
because it disables the early exit).
3. A topology with clock skew: the correct merge base has a lower committer
date than one of its ancestors that is also a common ancestor. With date
ordering, the deeper ancestor pops first and the early exit fires before
the correct result is found.
This two-patch series:
1. Adds a test demonstrating the bug (clock-skew topology where the correct
merge base has a lower date than its ancestor)
2. Fixes it by tracking whether the queue is generation-ordered and gating
the early exit on that flag
Kristofer Karlsson (2):
t6600: add test for merge-base early exit with clock skew
commit-reach: guard !FIND_ALL early exit with generation ordering
check
commit-reach.c | 10 +++++++---
t/t6600-test-reach.sh | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 3 deletions(-)
base-commit: 9aa172cd1f113276d360d4e48937dc95ef46b780
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2162%2Fspkrka%2Ffind-all-fix-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2162/spkrka/find-all-fix-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/2162
--
gitgitgadget
^ permalink raw reply
* [PATCH 1/2] t6600: add test for merge-base early exit with clock skew
From: Kristofer Karlsson via GitGitGadget @ 2026-06-29 13:19 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Derrick Stolee, Kristofer Karlsson,
Kristofer Karlsson
In-Reply-To: <pull.2162.git.1782739162.gitgitgadget@gmail.com>
From: Kristofer Karlsson <krka@spotify.com>
Add a topology where the correct merge base (M2) has a lower
committer date than its ancestor (M1) due to clock skew. With a
v1 commit graph (topological levels only, no corrected commit
dates), paint_down_to_common() falls back to commit-date ordering.
In that mode, M1 pops before M2, acquires both paint sides, and
the !FIND_ALL early exit fires -- returning the wrong merge base.
Mark the test as test_expect_failure to document the bug; the next
commit will fix it.
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
---
t/t6600-test-reach.sh | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/t/t6600-test-reach.sh b/t/t6600-test-reach.sh
index b5b314e570..1090104220 100755
--- a/t/t6600-test-reach.sh
+++ b/t/t6600-test-reach.sh
@@ -49,6 +49,42 @@ test_expect_success 'setup' '
git tag -a -m "$x-$i" tag-$x-$i commit-$x-$i || return 1
done
done &&
+ # Build a topology with clock skew to test the !FIND_ALL early
+ # exit in paint_down_to_common(). M2 is the correct merge base
+ # of P1 and P2, but its ancestor M1 has a higher committer date
+ # due to clock skew. With date-only ordering (v1 commit graph
+ # without corrected commit dates), M1 pops from the queue first,
+ # gets both paint sides, and the early exit fires before M2 is
+ # ever visited.
+ #
+ # P1 P2 @7000
+ # | / \
+ # A B D @6000
+ # / \ | |
+ # | M2--+ | @2000 (correct merge base)
+ # \ | |
+ # M1--------+ @5000 (clock skew: date > M2)
+ # |
+ # root @1000
+ #
+ git checkout --orphan skew-orphan &&
+ skew_tree=$(git mktree </dev/null) &&
+ skew_commit () {
+ GIT_COMMITTER_DATE="@$1 +0000" GIT_AUTHOR_DATE="@$1 +0000" \
+ git commit-tree -m "$2" "$skew_tree" $3 $4 $5 $6
+ } &&
+ skew_root=$(skew_commit 1000 root) &&
+ skew_M1=$(skew_commit 5000 M1 -p "$skew_root") &&
+ skew_M2=$(skew_commit 2000 M2 -p "$skew_M1") &&
+ skew_A=$(skew_commit 6000 A -p "$skew_M1" -p "$skew_M2") &&
+ skew_B=$(skew_commit 6000 B -p "$skew_M2") &&
+ skew_D=$(skew_commit 6000 D -p "$skew_M1") &&
+ skew_P1=$(skew_commit 7000 P1 -p "$skew_A") &&
+ skew_P2=$(skew_commit 7000 P2 -p "$skew_B" -p "$skew_D") &&
+ git branch -f skew-P1 "$skew_P1" &&
+ git branch -f skew-P2 "$skew_P2" &&
+ git tag skew-M2 "$skew_M2" &&
+
git commit-graph write --reachable &&
mv .git/objects/info/commit-graph commit-graph-full &&
chmod u+w commit-graph-full &&
@@ -967,4 +1003,9 @@ test_expect_success 'merge-base without --all is one of --all results' '
grep -F -f single all
'
+test_expect_failure 'merge-base without --all, clock skew, v1 commit-graph' '
+ git rev-parse skew-M2 >expect &&
+ merge_base_all_modes skew-P1 skew-P2
+'
+
test_done
--
gitgitgadget
^ permalink raw reply related
* [PATCH 2/2] commit-reach: guard !FIND_ALL early exit with generation ordering check
From: Kristofer Karlsson via GitGitGadget @ 2026-06-29 13:19 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Derrick Stolee, Kristofer Karlsson,
Kristofer Karlsson
In-Reply-To: <pull.2162.git.1782739162.gitgitgadget@gmail.com>
From: Kristofer Karlsson <krka@spotify.com>
When paint_down_to_common() falls back to commit-date ordering (for
v1 commit graphs without corrected commit dates), the !FIND_ALL early
exit incorrectly fires. The exit assumes the queue is generation-
ordered, so the first RESULT commit found must be the shallowest.
With date ordering this is not guaranteed: a closer merge base with
a lower committer date (clock skew) may still be in the queue behind
deeper commits.
Add a gen_ordered flag that is cleared when the date fallback fires,
and require it for the early exit.
Update the test from the previous commit to test_expect_success.
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
---
commit-reach.c | 10 +++++++---
t/t6600-test-reach.sh | 2 +-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/commit-reach.c b/commit-reach.c
index 5df471a313..708798a39b 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -108,11 +108,14 @@ static int paint_down_to_common(struct repository *r,
{ compare_commits_by_gen_then_commit_date }
};
int i;
+ int gen_ordered = 1;
timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
struct commit_list **tail = result;
- if (!min_generation && !corrected_commit_dates_enabled(r))
+ if (!min_generation && !corrected_commit_dates_enabled(r)) {
queue.pq.compare = compare_commits_by_commit_date;
+ gen_ordered = 0;
+ }
one->object.flags |= PARENT1;
if (!n) {
@@ -147,11 +150,12 @@ static int paint_down_to_common(struct repository *r,
commit->object.flags |= RESULT;
tail = commit_list_append(commit, tail);
/*
- * The queue is generation-ordered; no
- * remaining common ancestor can be a
+ * When the queue is generation-ordered,
+ * no remaining common ancestor can be a
* descendant of this one.
*/
if (!(mb_flags & MERGE_BASE_FIND_ALL) &&
+ gen_ordered &&
generation < GENERATION_NUMBER_INFINITY)
break;
}
diff --git a/t/t6600-test-reach.sh b/t/t6600-test-reach.sh
index 1090104220..0ff41381ff 100755
--- a/t/t6600-test-reach.sh
+++ b/t/t6600-test-reach.sh
@@ -1003,7 +1003,7 @@ test_expect_success 'merge-base without --all is one of --all results' '
grep -F -f single all
'
-test_expect_failure 'merge-base without --all, clock skew, v1 commit-graph' '
+test_expect_success 'merge-base without --all, clock skew, v1 commit-graph' '
git rev-parse skew-M2 >expect &&
merge_base_all_modes skew-P1 skew-P2
'
--
gitgitgadget
^ permalink raw reply related
* Re: [PATCH v6 4/4] history: re-edit a squash with every message
From: Harald Nordgren @ 2026-06-29 13:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Harald Nordgren via GitGitGadget, git
In-Reply-To: <xmqqwlvhzyhz.fsf@gitster.g>
> I doubt it would make practical difference, but one thing I notice
> is that unlike "git rebase -i", this one does not intersperse
> markers like "# This is the 1st commit message" in between the
> messages taken from the squashed commits, so it is not exactly
> "mirroring".
I wouldn't mind extracting that logic from 'rebase -i' to show it
here. It would be nice to have.
Harald
^ permalink raw reply
* Re: Security Vulnerability in Git 2.54.0/OpenSSL 3.5.6 Status
From: Johannes Schindelin @ 2026-06-29 13:57 UTC (permalink / raw)
To: Person, Tim; +Cc: git@vger.kernel.org
In-Reply-To: <SN4P221MB0713994458A94BFCB51F7AC494EA2@SN4P221MB0713.NAMP221.PROD.OUTLOOK.COM>
Hi Tim,
On Sat, 27 Jun 2026, Person, Tim wrote:
> I am writing to determine when Git plans to release an update installer
> to patch the security vulnerability in Git 2.54.0 because of the
> included OpenSSL executable. This vulnerability is rated "Critical" in
> the CVE (https://www.cve.org/CVERecord?id=CVE-2026-34182). An updated
> version of the OpenSSL.exe fixing this problem has been available since
> 06/12/2026. I am just wondering if/when you plan to address this major
> security issue.
OpenSSL.exe is not part of the critical path of Git for Windows. It is
merely included as a curiosity for historical reasons. The critical CVE
you mentioned does not affect anything in Git itself. Therefore, I did not
even consider making an out-of-band release of Git for Windows merely for
that OpenSSL v3.5.7 update.
The next Git for Windows release (v2.55.0, likely due later today, may
slip to tomorrow) will include OpenSSL v3.5.7.
Ciao,
Johannes
^ permalink raw reply
* Re: [PATCH 0/3] fixing expensive http test timeouts
From: Junio C Hamano @ 2026-06-29 14:39 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: Jeff King, Michael Montalbo, git
In-Reply-To: <akIfsaVMB_S6kfJQ@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
> By the way, the only reason why we at GitLab haven't been feeling the
> pain is that we only enable GIT_TEST_LONG for GitHub. So I was wondering
> whether we want to have something like the below patch on top.
If we can afford the cycles, it would be good to have similarly
larger coverage on two different platforms (compared to leaving one
of them not doing as much as the other when we know it). On the
other hand, if we cannot cover _everything_ in one platform, it may
be a better use of the resources to have the other platform things
that are not covered already. I see that among different pipeline
sources, we are doing TEST_LONG for pull requests to any branch, and
pushes only to "cast in stone" branches. If there are other
branches that deserve to be tested with TEST_LONG upon other events
that the existing GitHub Actions CI does not trigger, it may be good
to have GitLab CI cover them, perhaps?
>
> Patrick
>
> diff --git a/ci/lib.sh b/ci/lib.sh
> index b939110a6e..57801586aa 100755
> --- a/ci/lib.sh
> +++ b/ci/lib.sh
> @@ -215,6 +215,14 @@ then
> test macos != "$CI_OS_NAME" || CI_OS_NAME=osx
> CI_REPO_SLUG="$GITHUB_REPOSITORY"
> CI_JOB_ID="$GITHUB_RUN_ID"
> +
> + case "$GITHUB_EVENT_NAME" in
> + pull_request)
> + CI_EVENT=pull_request;;
> + push)
> + CI_EVENT=push;;
> + esac
> +
> CC="${CC_PACKAGE:-${CC:-gcc}}"
> DONT_SKIP_TAGS=t
> handle_failed_tests () {
> @@ -239,6 +247,13 @@ then
> CI_BRANCH="$CI_COMMIT_REF_NAME"
> CI_COMMIT="$CI_COMMIT_SHA"
>
> + case "$CI_PIPELINE_SOURCE" in
> + merge_request_event)
> + CI_EVENT=pull_request;;
> + push)
> + CI_EVENT=push;;
> + esac
> +
> case "$OS,$CI_JOB_IMAGE" in
> Windows_NT,*)
> CI_OS_NAME=windows
> @@ -319,7 +334,7 @@ export SKIP_DASHED_BUILT_INS=YesPlease
> # enable "expensive" tests for PR events.
> # In order to catch bugs introduced at integration time by mismerges,
> # enable the long tests for pushes to the integration branches as well.
> -case "$GITHUB_EVENT_NAME,$CI_BRANCH" in
> +case "$CI_EVENT,$CI_BRANCH" in
> pull_request,*|push,*next*|push,*master*|push,*main*|push,*maint*)
> export GIT_TEST_LONG=YesPlease
> ;;
^ permalink raw reply
* Re: [PATCH 2/3] t5551: put many-tags case into its own repo
From: Junio C Hamano @ 2026-06-29 14:42 UTC (permalink / raw)
To: Jeff King; +Cc: Michael Montalbo, Patrick Steinhardt, git
In-Reply-To: <20260629003434.GA1228461@coredump.intra.peff.net>
Jeff King <peff@peff.net> writes:
> On Sun, Jun 28, 2026 at 02:44:32PM -0700, Junio C Hamano wrote:
>
>> Jeff King <peff@peff.net> writes:
>>
>> > diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
>> > index e236e526f0..cd851f24b8 100755
>> > --- a/t/t5551-http-fetch-smart.sh
>> > +++ b/t/t5551-http-fetch-smart.sh
>> > @@ -397,15 +397,16 @@ create_tags () {
>> > }
>> >
>> > test_expect_success 'create 2,000 tags in the repo' '
>> > + git init "$HTTPD_DOCUMENT_ROOT_PATH/many-tags.git" &&
>> > (
>> > - cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
>> > + cd "$HTTPD_DOCUMENT_ROOT_PATH/many-tags.git" &&
>> > create_tags 1 2000
>> > )
>> > '
>>
>> While all the other repositories used in this tests are bare
>> repositories, this new one is a non-bare repository.
>>
>> It shouldn't make any difference, but since I noticed it...
>
> Ah, yeah. It should work either way, but it is slightly confusing for it
> to be non-bare. I'll wait to re-send (though if nothing else comes up,
> it may be simpler for you to just amend on your side).
OK. It seems both Patrick and you are in favor of using only [1/3]
& [2/3] but dropping [3/3]? If that is the concensus I can just
tweak this one and apply before 2.55 final.
Thanks.
^ permalink raw reply
* Re: [PATCH v4 1/1] environment: move excludes_file into repo_config_values
From: Junio C Hamano @ 2026-06-29 14:47 UTC (permalink / raw)
To: Christian Couder
Cc: Tian Yuchen, git, cirnovskyv, szeder.dev, Ayush Chandekar,
Olamide Caleb Bello
In-Reply-To: <CAP8UFD3Z0M_1NEXGcAxNZKpRUQiSkHZLTEvNNYushKA_PoPgjA@mail.gmail.com>
Christian Couder <christian.couder@gmail.com> writes:
> I agree that the best end state would be to have no `if (!repo ||
> !repo->initialized)` check, but we shouldn't have to get there right
> away. I think it's fine to proceed in several steps:
>
> 1) `if (!repo || !repo->initialized) return NULL;` allows us to remove
> the global variable and use getters which will help us in the next
> step.
>
> 2) `if (!repo || !repo->initialized) return BUG("repo must be an
> initialized repository");` now we want to find and fix callers
> (including tests) that haven't properly initialized things.
>
> 3) No `if (!repo || !repo->initialized)` check, as we are sure that
> all the callers that didn't properly initialized things have been
> found and fixed.
>
> So I think 1) is fine for now as long as we properly explain in the
> commit messages and in code comments (maybe using NEEDSWORK comments)
> that we know there is more work to do on this in the future.
I am OK with the progressive improvements, but if "wean us away from
global variables" topic stops at step 1 I would have to say that is
a failed experiment. Not doing (2) means you made the system bug-to-bug
compatible from the old world where these things weren't in repo-config
but were still globals, which is code churn for nothing good to show
in the end result. We need to get to (2) before declaring victory.
But of course, we need to start somewhere. (1) with in-code
comments sprinkled to such places that say that we'd need to revisit
would be a good place to start.
Thanks.
^ permalink raw reply
* Re: [PATCH v6 4/4] history: re-edit a squash with every message
From: Junio C Hamano @ 2026-06-29 14:49 UTC (permalink / raw)
To: Harald Nordgren; +Cc: Harald Nordgren via GitGitGadget, git
In-Reply-To: <CAHwyqnXXFz4z_ULUq7Oqu0ykwpLJyEyW-uoF2bKfoYZQAjrNdQ@mail.gmail.com>
Harald Nordgren <haraldnordgren@gmail.com> writes:
>> I doubt it would make practical difference, but one thing I notice
>> is that unlike "git rebase -i", this one does not intersperse
>> markers like "# This is the 1st commit message" in between the
>> messages taken from the squashed commits, so it is not exactly
>> "mirroring".
>
> I wouldn't mind extracting that logic from 'rebase -i' to show it
> here. It would be nice to have.
If we can share more code (not necessarily the exact existing
code---after cleaning it up if needed is perfectly fine and may even
be better) across codebaes that would be excellent. Thanks.
^ permalink raw reply
* Re: [PATCH] history: streamline message preparation and plug file stream leak
From: Junio C Hamano @ 2026-06-29 15:21 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git, Johannes Schindelin
In-Reply-To: <akIRrmD4Tqp-Gi9d@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
>> + strbuf_addstr(out, default_message);
>> + strbuf_addch(out, '\n');
>> + strbuf_commented_addf(out, comment_line_str, hint, action, comment_line_str);
>> + fwrite(out->buf, 1, out->len, s.fp);
>>
>> wt_status_collect_changes_trees(&s, old_tree, new_tree);
>> wt_status_print(&s);
>> wt_status_collect_free_buffers(&s);
>> string_list_clear_func(&s.change, change_data_free);
>> + fclose(s.fp);
>
> This is fixing the leaked file descriptor.
>
> One thing I wonder though is that we don't perform any error checking on
> the file in the new version. Previously, we would have died in case
> `write_file_buf()` failed. But now we just `fwrite()` without error
> checking. I don't think that "wt-status.c" does error checking either,
> so we might end up with a partially-written file without us noticing.
Yes, the fwrite() should be protected with an error checking and
die() the same way as the code before. Will send a v2.
But isn't the end result the same between preimage and postimage?
If the stuff appended by wt_status_* are still written without error
checking, we would leave a partially-written file that has the
default_messages and the commented hint/action but not necessarily
whatever we wanted to add with wt_status().
^ permalink raw reply
* Re: receive-pack hangs on zero-object push into promisor-shaped repository
From: Patrick Steinhardt @ 2026-06-29 15:30 UTC (permalink / raw)
To: Wei Hu; +Cc: git
In-Reply-To: <CACLXMtCSzW9BY7idqB1yGa87MeG0Y2FN5Ho2hRXuPJ_qswE27Q@mail.gmail.com>
On Mon, Jun 29, 2026 at 03:10:42PM +0800, Wei Hu wrote:
> Hello,
>
> I found a reproducible hang in `git receive-pack` when pushing a ref update
> that sends zero objects into a repository that has promisor remote
> configuration and `.promisor` pack sidecar files.
>
> The same zero-object ref update returns normally when the receiving
> repository is a normal non-bare repository or a bare repository. It
> also returns normally if I remove either the promisor remote config or
> the `.promisor` sidecar files from the receiving repository.
>
> Check the attached script to reproduce the bug.
Thanks for your report! I was able to reduce your test case to the
following minimal reproducer:
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 1c2805acca..2850e78e49 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -723,6 +723,28 @@ test_expect_success 'after fetching descendants of non-promisor commits, gc work
git -C partial gc --prune=now
'
+test_expect_success 'zero-object push does not hang' '
+ rm -rf src dst &&
+
+ git init src &&
+ test_commit -C src initial &&
+
+ git init --bare dst &&
+ git -C src push "$(pwd)/dst" main &&
+ git -C dst config set remote.origin.promisor true &&
+ git -C dst maintenance run &&
+ for pack in dst/objects/pack/*.pack
+ do
+ >"${pack%.pack}.promisor" || return 1
+ done &&
+
+ # Push the already-existing commit with a new branch name, which
+ # results in zero objects being written. This used to hang in the past.
+ git -C src push "$(pwd)/dst" main:topic &&
+ git -C src rev-parse main >expect &&
+ git -C dst rev-parse topic >actual &&
+ test_cmp expect actual
+'
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
As it turns out, the bug itself was fixed already via d9982e8290
(connected: close err_fd in promisor fast-path, 2026-05-15), and that
fix is going to be part of Git 2.55 (which is due today).
That commit didn't add a test for this scenario though, even though the
commit message points out that there's been multiple regressions in this
area already. It's probably worth it to add the above test to our test
suite. Is this something you'd like to do? Otherwise I'm happy to send a
patch.
Thanks!
Patrick
^ permalink raw reply related
* Re: [PATCH v5 0/4] history: add squash subcommand to fold a range
From: Phillip Wood @ 2026-06-29 15:51 UTC (permalink / raw)
To: Patrick Steinhardt, phillip.wood
Cc: Harald Nordgren via GitGitGadget, git, Harald Nordgren
In-Reply-To: <akIQLM6xZTHBudWT@pks.im>
Hi Harald and Patrick
On 29/06/2026 07:26, Patrick Steinhardt wrote:
> On Fri, Jun 26, 2026 at 09:52:57AM +0100, Phillip Wood wrote:
>> Hi Harald
>>
>> On 24/06/2026 22:54, Harald Nordgren via GitGitGadget wrote:
>>> Adds git history squash <revision-range> to fold a range of commits.
>>
>> It would be helpful to give a bit more detail here about the command so that
>> the reader has an overview of what is actually being implemented.
>>
>> - what does it do with fixup!, squash! and amend! commits? Can it use
>> the message from amend! commits to reword the commit?
>> - can the user reword the commit message?
>
> Good things to document/discuss.
Thanks, I was disappointed that these questions were not addressed in
the cover letter for v6 which contains no more detail than this one.
We should make rewording the commit as easy as possible to encourage
users to create useful commit histories. I think that means having some
support for fixup! style commits. We could just do what rebase does and
comment out the fixup! style commit subjects and the commit messages
replaced by amend! commits but I think we have the opportunity to do
something nicer (I find the commented-out messages annoying). We could
have a comment saying "this is the combination of the following commits"
followed by a list of the subject lines and then in the template message
we'd simply omit the useless fixup! subjects when the commit body is
empty and also omit the original commit messages that have been replaced
by an amend! commit.
So instead of
# This is the combination of 4 commits
# This is the first commit message
Base subject
Base body
# This is the second commit message
# Another subject
# Another body
# This is the third commit message
# fixup! Base subject
# This is the fourth commit message
# amend! Another subject
A better subject
A better body
We'd have
# This is the combination of 4 commits
# 123 Base subject
# 456 Another subject
# 789 fixup! Base subject
# abc amend! Another subject
Base Subject
Base Body
Another subject
Another Body
Possibly with a comment before each message saying where it came from.
It would be good to error out if the user tries squash a fixup! style
commit and range does not contain its target commit.
In the long run we should provide a way to squash an arbitrary list of
commits rather than just a range.
>
>> - what happens if a merge commit inside the range has a parent outside
>> the range?
>
> Yeah, I agree that we should punt on merge commits for now. They are a
> can of worms, and I'm not sure that we should just squash them. I would
> at least like the user to ask a flag that tells us that it's fine
> squashing those.
There does seem to be some support for merges in this patch series which
I think behaves pretty sensibly. If we have
C - D
/ \
- A - B - E - F - G
Then squashing A..G should be fine because the parents of F are in the
range and it looks like we support that. Squashing should B..G without
--ancestry-path should be safe as well because B ends up as the parent
of the squashed commit but we don't have a way to disable
--ancestry-path (and maybe we don't want to add one). Squashing F^@..G
might be useful to fixup a merge (though perhaps amending F rather than
creating G is a simpler way to fix a broken merge). Squashing E..G does
not make sense because the range does not include one of the merge parents.
>> - what happens to branches that point to commits inside the range?
>
> Yeah, this should be documented indeed.
>
>> I had a quick play and found that it accepts ranges that containing a single
>> commit (e.g. @^!) where there is nothing to squash. It also accepts ranges
>> that are not ancestors of HEAD (e.g. checkout master and run "git history
>> squash --dry-run origin/seen^2^!") without printing an error message. Only
>> accepting a single argument is quite limiting as one cannot say
>>
>> git history squash ^:/base :/tip
We should sanitize what the user passes though - we do not want to
accept arbitrary rev-list options. Off the top of my head "--left-only"
and "--right-only" would allow the use of "A...B" and allowing "--not"
seems reasonable.
> Note that it is intentional that you can rewrite branches that are not
> currently checked out, and the other subcommands work the same. So I'd
> argue this should also be the case for "squash".
Ah, thanks for clarifying that - it does not seem to check that there is
a branch to be rewritten though if I do
./git checkout origin/master
./git history squash --dry-run origin/seen^2^^..origin/seen^2
there is no error message and it exits 0. If I create a branch pointing
at origin/seen^2 then it does print a sensible ref-update.
Thanks
Phillip
^ permalink raw reply
* Re: [PATCH] history: streamline message preparation and plug file stream leak
From: Patrick Steinhardt @ 2026-06-29 16:04 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Johannes Schindelin
In-Reply-To: <xmqq33y5z82l.fsf@gitster.g>
On Mon, Jun 29, 2026 at 08:21:06AM -0700, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
>
> >> + strbuf_addstr(out, default_message);
> >> + strbuf_addch(out, '\n');
> >> + strbuf_commented_addf(out, comment_line_str, hint, action, comment_line_str);
> >> + fwrite(out->buf, 1, out->len, s.fp);
> >>
> >> wt_status_collect_changes_trees(&s, old_tree, new_tree);
> >> wt_status_print(&s);
> >> wt_status_collect_free_buffers(&s);
> >> string_list_clear_func(&s.change, change_data_free);
> >> + fclose(s.fp);
> >
> > This is fixing the leaked file descriptor.
> >
> > One thing I wonder though is that we don't perform any error checking on
> > the file in the new version. Previously, we would have died in case
> > `write_file_buf()` failed. But now we just `fwrite()` without error
> > checking. I don't think that "wt-status.c" does error checking either,
> > so we might end up with a partially-written file without us noticing.
>
> Yes, the fwrite() should be protected with an error checking and
> die() the same way as the code before. Will send a v2.
>
> But isn't the end result the same between preimage and postimage?
> If the stuff appended by wt_status_* are still written without error
> checking, we would leave a partially-written file that has the
> default_messages and the commented hint/action but not necessarily
> whatever we wanted to add with wt_status().
At least it would only be the status information that's missing in that
case, the commit message itself would be retained (or we'd die if it
wasn't written). So we didn't have the potential to loose information
that is intended to end up in the final commit.
Patrick
^ permalink raw reply
* [PATCH v2] history: streamline message preparation and plug file stream leak
From: Junio C Hamano @ 2026-06-29 16:08 UTC (permalink / raw)
To: git; +Cc: Patrick Steinhardt, Johannes Schindelin
In-Reply-To: <xmqqecht8df1.fsf@gitster.g>
An early part of fill_commit_message() function uses write_file_buf()
to write out what was prepared in a strbuf, which is primarily meant
for use by callers that have their own message prepared fully and
called as the last thing to flush it to the destination file.
However, the function then opens a file stream in append mode to
further write into it. It may have been understandable if this was
a later addition, but it seems it came from a single commit,
d205234c (builtin/history: implement "reword" subcommand,
2026-01-13), which is somewhat puzzling, but anyway...
Just open the file stream upfront for writing, write the message
the function has in the strbuf, and then keep writing whatever it
wants to write to the same open file stream.
And do not forget to close the stream. We are about to pass the
resulting file to an external editor, and on some systems, notably
Windows, you are not supposed to keep a file open while expecting
another program to access it.
Diagnosed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
* Changes from v1 are two additional error checks to notice failure
from fwrite() and fclose() to die. Interdiff appears at the end.
builtin/history.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/builtin/history.c b/builtin/history.c
index 8dcb9a6046..365e81379b 100644
--- a/builtin/history.c
+++ b/builtin/history.c
@@ -41,11 +41,6 @@ static int fill_commit_message(struct repository *repo,
" empty message aborts the commit.\n");
struct wt_status s;
- strbuf_addstr(out, default_message);
- strbuf_addch(out, '\n');
- strbuf_commented_addf(out, comment_line_str, hint, action, comment_line_str);
- write_file_buf(path, out->buf, out->len);
-
wt_status_prepare(repo, &s);
FREE_AND_NULL(s.branch);
s.ahead_behind_flags = AHEAD_BEHIND_QUICK;
@@ -57,14 +52,22 @@ static int fill_commit_message(struct repository *repo,
s.whence = FROM_COMMIT;
s.committable = 1;
- s.fp = fopen(git_path_commit_editmsg(), "a");
+ s.fp = fopen(path, "w");
if (!s.fp)
- return error_errno(_("could not open '%s'"), git_path_commit_editmsg());
+ return error_errno(_("could not open '%s'"), path);
+
+ strbuf_addstr(out, default_message);
+ strbuf_addch(out, '\n');
+ strbuf_commented_addf(out, comment_line_str, hint, action, comment_line_str);
+ if (fwrite(out->buf, 1, out->len, s.fp) != out->len)
+ die_errno(_("could not write to '%s'"), path);
wt_status_collect_changes_trees(&s, old_tree, new_tree);
wt_status_print(&s);
wt_status_collect_free_buffers(&s);
string_list_clear_func(&s.change, change_data_free);
+ if (fclose(s.fp))
+ die_errno(_("could not write to '%s'"), path);
strbuf_reset(out);
if (launch_editor(path, out, NULL)) {
Interdiff against v1:
diff --git a/builtin/history.c b/builtin/history.c
index f17ec049c0..365e81379b 100644
--- a/builtin/history.c
+++ b/builtin/history.c
@@ -59,13 +59,15 @@ static int fill_commit_message(struct repository *repo,
strbuf_addstr(out, default_message);
strbuf_addch(out, '\n');
strbuf_commented_addf(out, comment_line_str, hint, action, comment_line_str);
- fwrite(out->buf, 1, out->len, s.fp);
+ if (fwrite(out->buf, 1, out->len, s.fp) != out->len)
+ die_errno(_("could not write to '%s'"), path);
wt_status_collect_changes_trees(&s, old_tree, new_tree);
wt_status_print(&s);
wt_status_collect_free_buffers(&s);
string_list_clear_func(&s.change, change_data_free);
- fclose(s.fp);
+ if (fclose(s.fp))
+ die_errno(_("could not write to '%s'"), path);
strbuf_reset(out);
if (launch_editor(path, out, NULL)) {
--
2.55.0-180-gf61bfe2e0b
^ permalink raw reply related
* Re: [PATCH 0/3] fixing expensive http test timeouts
From: Patrick Steinhardt @ 2026-06-29 16:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, Michael Montalbo, git
In-Reply-To: <xmqqldbxz9z4.fsf@gitster.g>
On Mon, Jun 29, 2026 at 07:39:59AM -0700, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
>
> > By the way, the only reason why we at GitLab haven't been feeling the
> > pain is that we only enable GIT_TEST_LONG for GitHub. So I was wondering
> > whether we want to have something like the below patch on top.
>
> If we can afford the cycles, it would be good to have similarly
> larger coverage on two different platforms (compared to leaving one
> of them not doing as much as the other when we know it). On the
> other hand, if we cannot cover _everything_ in one platform, it may
> be a better use of the resources to have the other platform things
> that are not covered already. I see that among different pipeline
> sources, we are doing TEST_LONG for pull requests to any branch, and
> pushes only to "cast in stone" branches. If there are other
> branches that deserve to be tested with TEST_LONG upon other events
> that the existing GitHub Actions CI does not trigger, it may be good
> to have GitLab CI cover them, perhaps?
I'm a bit hesitant to do such a split, mostly because the canonical
source of truth that the project typically uses is GitHub's CI. So I
want us at GitLab to be able to catch the same issues that GitHub would
flag. And if GitLab's CI stopped detecting everything that GitHub does,
then the result would likely be that we often create merge requests on
both platforms, which would only result in more wasted resources.
Patrick
^ permalink raw reply
* Re: [PATCH v5 0/4] history: add squash subcommand to fold a range
From: Harald Nordgren @ 2026-06-29 16:09 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: phillip.wood, Harald Nordgren via GitGitGadget, git
In-Reply-To: <akIQLM6xZTHBudWT@pks.im>
> Yeah, I agree that we should punt on merge commits for now. They are a
> can of worms, and I'm not sure that we should just squash them. I would
> at least like the user to ask a flag that tells us that it's fine
> squashing those.
Do you mean not even handling simple merges that are fully within the
range? I'm already handling those, so remove?
Harald
^ permalink raw reply
* Re: [PATCH 0/3] fixing expensive http test timeouts
From: Junio C Hamano @ 2026-06-29 16:19 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: Jeff King, Michael Montalbo, git
In-Reply-To: <akKYv3nqX0BXcavu@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
>> pushes only to "cast in stone" branches. If there are other
>> branches that deserve to be tested with TEST_LONG upon other events
>> that the existing GitHub Actions CI does not trigger, it may be good
>> to have GitLab CI cover them, perhaps?
>
> I'm a bit hesitant to do such a split, mostly because the canonical
> source of truth that the project typically uses is GitHub's CI. So I
> want us at GitLab to be able to catch the same issues that GitHub would
> flag. And if GitLab's CI stopped detecting everything that GitHub does,
> then the result would likely be that we often create merge requests on
> both platforms, which would only result in more wasted resources.
I didn't suggest splitting them into two circles that overlap but
each with area only it covers, though. GitLab's coverage can be
superset to GitHub's and that would satify what I suggested.
FWIW, I do not consider GitHub's CI "the canonical source" at all.
It is a very handy service to use to check how well we are doing,
but from time to time it has its own hiccups ;-).
What can we do to make the visibility of GitLab's CI more prominent?
I know where the CI jobs that are triggered when I push out the
integration branches are found at GitHub's website[*], but I do not
think I know the corresponding one at GitLab, for example, and I
think that is a shame.
[Footnote]
*1* I just made https://tinyurl.com/github-gitci that points at
https://github.com/git/git/actions/workflows/main.yml?query=event%3Apush+actor%3Agitster
^ permalink raw reply
* Re: [PATCH v5 0/4] history: add squash subcommand to fold a range
From: Junio C Hamano @ 2026-06-29 16:54 UTC (permalink / raw)
To: Phillip Wood
Cc: Patrick Steinhardt, phillip.wood,
Harald Nordgren via GitGitGadget, git, Harald Nordgren
In-Reply-To: <3b3af3ef-a043-4af9-964e-429237789c97@gmail.com>
Phillip Wood <phillip.wood123@gmail.com> writes:
> It would be good to error out if the user tries squash a fixup! style
> commit and range does not contain its target commit.
That's interesting. It at least deserves a warning, even though the
choice to leave them out, with intentions to make it a separate fix
on top, may be deliberate. If such a change-of-mind-in-the-middle
is rare, then erroring out would be perfect. The user can first
reword the !fixup to make it a separate fix and then squash the
range in quesiton.
> We should sanitize what the user passes though - we do not want to
> accept arbitrary rev-list options. Off the top of my head "--left-only"
> and "--right-only" would allow the use of "A...B" and allowing "--not"
> seems reasonable.
I would not recommend guessing what these rev-list "expressions"
would produce and blacklist some of the operations and notations.
It would be a more robust approach to let the machinery do its thing
to determine the set of commits, *and* inspect the shape of the
history these commits represent. Are they connected? Do they have
a single "bottom" that is just outside and below the range so that
we can replace it with the result of squashing everything together?
Do they have a single "top" whose children can be rewritten to have
the resulting single commit as one of their parents? Starting from
the acceptable shape of the history we want to deal with, rather
than trying to enumerate rev-list operations and notations that
would prevent the resulting set of commits to fall outside the
acceptable shape of the history (and I am reasonably sure anybody
who attempts to do so would either end up with unusablly narrow
subset of what we can reasonably handle, or miss some cases that we
do not want to handle), would be a better approach.
^ permalink raw reply
* Re: [PATCH 1/6] packfile: thread odb_source_packed through packed_object_info()
From: Justin Tobler @ 2026-06-29 17:01 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <20260624-b4-pks-odb-drop-whence-v1-1-8d1877b790ac@pks.im>
On 26/06/24 02:19PM, Patrick Steinhardt wrote:
> Add an optional `struct odb_source_packed *source` parameter to
> `packed_object_info()` and `packed_object_info_with_index_pos()`. This
> parameter is unused at this point in time, but it will be used in a
> follow-up commit so that we can record the source of a specific object.
Ok so `packed_object_info()` is responsible for populating `struct
object_info` from the provided packfile and object offset. By
additionally providing the object source, the ultimate goal is to store
the this information in `struct object_info` or some equivalent
structure.
At first, I wondered if it would make more sense for `struct packed_git`
to record the `struct odb_source_packed` it comes from, but maybe that
wouldn't be the best layer to handle this bookkeeping?
> Note that callers in "odb/source-packed.c" pass the already-available
> source, but all other callers pass `NULL` instead. This is fine though,
> as we only care about populating this info when called via the packed
> store.
Hmmm, is this because knowing the ODB source the object comes from is
only useful for callers from in "odb/source-packed.c"? Maybe this will
become a bit more clear to me in subsequent patches.
The patch itself is just wiring up `struct odb_source_packed` to the
above mentioned functions, but doesn't do anything yet with them. This
step looks trivially correct though.
-Justin
^ permalink raw reply
* [ANNOUNCE] Git v2.55.0
From: Junio C Hamano @ 2026-06-29 17:10 UTC (permalink / raw)
To: git; +Cc: Linux Kernel, git-packagers
The latest feature release Git v2.55.0 is now available at the
usual places. It is comprised of 505 non-merge commits since
v2.54.0, contributed by 100 people, 33 of which are new faces [*].
The tarballs are found at:
https://www.kernel.org/pub/software/scm/git/
The following public repositories all have a copy of the 'v2.55.0'
tag and the 'master' branch that the tag points at:
url = https://git.kernel.org/pub/scm/git/git
url = https://kernel.googlesource.com/pub/scm/git/git
url = git://repo.or.cz/alt-git.git
url = https://github.com/gitster/git
New contributors whose contributions weren't in v2.54.0 are as follows.
Welcome to the Git development community!
Abhinav Gupta, Aliwoto, Arijit Banerjee, Brandon Chinn, Claude
Sonnet 4.6, David Lin, Dominik Loidolt, Ethan Dickson, Hugo
Osvaldo Barrera, Ivan Baluta, Jean-Christophe Manciot, Jonas
Rebmann, Kévin Leprêtre, Koutian Wu, Kristofer Karlsson,
Kushal Das, lilydjwg, Luke Martin, Luna Schwalbe, Matheus
Afonso Martins Moreira, Matteo Beniamino, Michael Grossfeld,
Owen Stephens, Rob McDonald, Saagar Jha, Scott Bauersfeld,
Scott L. Burson, Sebastien Tardif, Shardul Natu, Siddh Raman
Pant, slonkazoid, Tamir Duberstein, and Weijie Yuan.
Returning contributors who helped this release are as follows.
Thanks for your continued support.
Adam Johnson, Adrian Ratiu, Ævar Arnfjörð Bjarmason, Aindriú
Mac Giolla Eoin, Alexander Monakov, Alexander Shopov, Alyssa
Ross, Andrew Kreimer, Arkadii Yakovets, Bagas Sanjaya, brian
m. carlson, Christian Couder, D. Ben Knoble, Derrick Stolee,
Elijah Newren, Emily Shaffer, Emir SARI, Ezekiel Newren, Fangyi
Zhou, Ghanshyam Thakkar, Greg Hurrell, Harald Nordgren, Jacob
Keller, Jan Palus, Jayesh Daga, Jean-Noël Avila, Jeff King,
Jiang Xin, Johannes Schindelin, Johannes Sixt, Jonatan Holmgren,
Junio C Hamano, Justin Tobler, Karthik Nayak, Kate Golovanova,
Kristoffer Haugsbakk, LorenzoPegorari, Lucas Seiki Oshiro,
Lumynous, Mark Levedahl, Matthew John Cheetham, Michael
Montalbo, Mikel Forcada, Mirko Faina, Olamide Caleb Bello,
Pablo Sabater, Patrick Steinhardt, Paul Tarjan, Peter Krefting,
Philippe Blain, Phillip Wood, Pushkar Singh, Ramsay Jones, René
Scharfe, Samo Pogačnik, Shreyansh Paliwal, Siddharth Asthana,
Siddharth Shrimali, SZEDER Gábor, Taylor Blau, Todd Zullinger,
Toon Claes, Torsten Bögershausen, Trieu Huynh, Tuomas Ahola,
Usman Akinyemi, and Zakariyah Ali.
[*] We are counting not just the authorship contribution but issue
reporting, mentoring, helping and reviewing that are recorded in
the commit trailers.
----------------------------------------------------------------
Git v2.55 Release Notes
=======================
UI, Workflows & Features
------------------------
* Hook scripts defined via the configuration system can now be
configured to run in parallel.
* The userdiff driver for the Scheme language has been extended to
cover other Lisp dialects.
* Terminal control sequences coming over the sideband while talking
to a remote repository are mostly disabled by default, except for
ANSI color escape sequences.
* "ort" merge backend improvements.
* "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.
* A new builtin "git format-rev" is introduced for pretty formatting
one revision expression per line or commit object names found in
running text.
* "git history" learned "fixup" command.
* The internal URL parsing logic has been made accessible via a new
subcommand "git url-parse".
* Misspelt proxy URL (e.g., httt://...) did not trigger any warning
or failure, which has been corrected. We had a regression in this
update that broke https:// proxies, but that has been caught and
corrected.
* Document the fact that .git/info/exclude is shared across worktrees
linked to the same repository.
* The command line parser for "git diff" learned a few options take
only non-negative integers.
* The graph output from commands like "git log --graph" can now be
limited to a specified number of lanes, preventing overly wide output
in repositories with many branches.
* The fsmonitor daemon has been implemented for Linux.
* "git cat-file --batch" learns an in-line command "mailmap"
that lets the user toggle use of mailmap.
* The "git pack-objects --path-walk" traversal has been integrated
with several object filters, including blobless and sparse filters.
* "git push" learned to take a "remote group" name to push to, which
causes pushes to multiple places, just like "git fetch" would do.
* The 'git-jump' command (in contrib/) has been taught to automatically
pick a mode (merge, diff, or ws) when invoked without arguments.
* The documentation for `push.default = simple` has been clarified to
better explain its behavior, making it clear that it pushes the
current branch to a same-named branch on the remote, and detailing
the upstream requirements for centralized workflows.
* The documentation for "--word-diff" has been extended with a bit of
implementation detail of where these different words come from.
* "git config foo.bar=baz" is not likely to be a request to read the
value of such a variable with '=' in its name; rather it is plausible
that the user meant "git config set foo.bar baz". Give advice when
giving an error message.
* "git rev-list" (and "git log" family of commands) learned a new "--max-count-oldest"
that picks oldest N commits in the range instead of the usual newest.
* Various AsciiDoc markup fixes in 'git config' documentation and
related files to ensure lists and formatting are rendered correctly.
Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
* Promisor remote handling has been refactored and fixed in
preparation for auto-configuration of advertised remotes.
* Rust support is enabled by default (but still allows opting out) in
some future version of Git.
* Preparation of the xdiff/ codebase to work with Rust.
* Use a larger buffer size in the code paths to ingest pack stream.
* Refactor service routines in the ref subsystem backends.
* Shrink wasted memory in Myers diff that does not account for common
prefix and suffix removal.
* Enable expensive tests to catch topics that may cause breakages on
integration branches closer to their origin in the contributor PR
builds.
* "git merge-base" optimization.
* The limit_list() function that is one of the core part of the
revision traversal infrastructure has been optimized by replacing
its use of linear list with priority queue.
* In a lazy clone, "git cherry" and "git grep" often fetch necessary
blob objects one by one from promisor remotes. It has been corrected
to collect necessary object names and fetch them in bulk to gain
reasonable performance.
* The logic to determine that branches in an octopus merge are
independent has been optimized.
* The consistency checks for the files reference backend have been updated
to skip lock files earlier, avoiding unnecessary parsing of
intermediate files.
* The negotiation tip options in "git fetch" have been reworked to
allow requiring certain refs to be sent as "have" lines, and to
restrict negotiation to a specific set of refs.
* The repacking code has been refactored and compaction of MIDX layers
have been implemented, and incremental strategy that does not require
all-into-one repacking has been introduced.
* ODB transaction interface is being reworked to explicitly handle
object writes.
* Add a new odb "in-memory" source that is meant to only hold
tentative objects (like the virtual blob object that represents the
working tree file used by "git blame").
* Many uses of the_repository has been updated to use a more
appropriate struct repository instance in setup.c codepath.
* Revision traversal optimization.
* Build update.
* The logic to lazy-load trees from the commit-graph has been made
more robust by falling back to reading the commit object when
the commit-graph is no longer available.
* The "name" argument in git_connect() and related functions has been
converted to a "service" enum to improve type safety and clarify its
purpose.
* 'git restore --staged' has been optimized to avoid unnecessarily expanding
the sparse index when operating on paths within the sparse checkout
definition, by handling sparse directory entries at the tree level.
* "git stash -p" has been optimized by reusing cached index
entries in its temporary index, avoiding unnecessary lstat()
calls on unchanged files.
* The check for non-stale commits in the priority queue used by
`paint_down_to_common` and `ahead_behind` has been optimized by
replacing an O(N) scan with an O(1) counter, yielding performance
improvements in repositories with wide histories.
* Reachability bitmap generation has been significantly optimized. By
reordering tree traversal, caching object positions, and refining how
pseudo-merge bitmaps are constructed, the performance of "git repack
--write-midx-bitmaps" is improved, especially for large repositories
and when using pseudo-merges.
* Adding a decimal integer with strbuf_addf("%u") appears commonly;
they have been optimized by using a custom formatter.
* Formatting object name in full hexadecimal form has been optimized
by using a new strbuf_add_oid_hex() helper function.
* Encourage original authors to monitor the CI status.
* The `git log -L` implementation has been refactored to use the
standard diff output pipeline, enabling pickaxe and diff-filter to
work as expected. Additionally, metadata-only diff formats like
--raw and --name-only are now supported with -L.
* The loose object source has been refactored into a proper `struct
odb_source`.
* Guidelines on how to write a cover letter for a multi-patch series
have been added to SubmittingPatches, which also got a new marker
to separate the section for typofixes.
* The setup logic to discover and configure repositories has been
refactored, and the initialization of the object database has been
centralized.
* Many core configuration variables have been migrated from global
variables into 'repo_config_values' to tie them to a specific
repository instance, avoiding cross-repository state leakage.
* Streaming revision walks have been optimized by using a priority queue
for date-sorting commits, speeding up walks repositories with many
merges.
* A recent regression in t7527 that broke TAP output has been fixed,
some other test noise that also broke TAP output has been silenced,
and 'prove' is now configured to fail on invalid TAP output to
prevent future regressions.
* A handful of inappropriate uses of the_repository have been
rewritten to use the right repository structure instance in the
unpack-trees.c codepath.
* "git index-pack" has been optimized by retaining child bases in the
delta cache instead of immediately freeing them, letting the existing
cache limit policy decide eviction.
* `git ls-files --modified` and `git ls-files --deleted` have been
optimized to filter with pathspec before calling lstat() when there is
only a single pathspec item, avoiding unnecessary filesystem access
for entries that will not be shown.
* The UNUSED macro in 'compat/posix.h' has been updated to use a
newly introduced GIT_CLANG_PREREQ macro for compiler version
checks, and the existing GIT_GNUC_PREREQ macro has been modernized
to use explicit major/minor comparisons rather than bit-shifting.
* Wean the Windows builds in GitLab CI procedure away from
(unfortunately unreliable) Chocolatey to install dependencies.
(merge 0e7b51fed2 ps/gitlab-ci-windows later to maint).
* Build-fix for 32-bit Windows.
* Xcode 15 and later has a linker set to complain when the same library
archive is listed twice on the command line. Squelch the annoyance.
Fixes since v2.54
-----------------
* Code clean-up to use the right instance of a repository instance in
calls inside refs subsystem.
(merge 57c590feb9 sp/refs-reduce-the-repository later to maint).
* 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.
(merge 521731213c dl/cache-tree-fully-valid-fix later to maint).
* 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.
(merge ffe8005b9d ps/test-set-e-clean later to maint).
* Revert a recent change that introduced a regression to help mksh users.
* Update various GitHub Actions versions.
* Avoid hitting the pathname limit for socks proxy socket during the
test..
* To help Windows 10 installations, avoid removing files whose
contents are still mmap()'ed.
* 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.
(merge a1ad4a0fca en/backfill-fixes-and-edges later to maint).
* "git grep" update.
(merge 9ff4b5ab1b rs/grep-column-only-match-fix later to maint).
* Headers from glibc 2.43 when used with clang does not allow
disabling C11 language features, causing build failures..
* The 'http.emptyAuth=auto' configuration now correctly attempts
Negotiate authentication before falling back to manual credentials.
This allows seamless Kerberos ticket-based authentication without
requiring users to explicitly set 'http.emptyAuth=true'.
(merge 4919938d28 mc/http-emptyauth-negotiate-fix later to maint).
* Ramifications of turning off commit-graph has been documented a bit
more clearly.
(merge 48c855bb8f kh/doc-commit-graph later to maint).
* "git rebase --update-refs", when used with an rebase.instructionFormat
with "%d" (describe) in it, tried to update local branch HEAD by
mistake, which has been corrected.
(merge 106b6885c7 ag/rebase-update-refs-limit-to-branches later to maint).
* Tweak the way how sideband messages from remote are printed while
we talk with a remote repository to avoid tickling terminal
emulator glitches.
(merge 31e8fcabd8 rs/sideband-clear-line-before-print later to maint).
* The configuration variable submodule.fetchJobs was not read correctly,
which has been corrected.
(merge aa45a5902f sj/submodule-update-clone-config-fix later to maint).
* Update code paths that assumed "unsigned long" was long enough for
"size_t".
(merge 7a094d68a2 js/objects-larger-than-4gb-on-windows later to maint).
* Stop using unmaintained custom allocator in Windows build which was
the last user of the code.
* The computation to shorten the filenames shown in diffstat measured
width of individual UTF-8 characters to add up, but forgot to take
into account error cases (e.g., an invalid UTF-8 sequence, or a
control character).
(merge 09d86a3b98 en/diffstat-utf8-truncation-fix later to maint).
* Some tests assume that bare repository accesses are by default
allowed; rewrite some of them to avoid the assumption, rewrite
others to explicitly set safe.bareRepository to allow them.
(merge 985b38ca6c js/adjust-tests-to-explicitly-access-bare-repo later to maint).
* Signing commit with custom encoding was passing the data to be
signed at a wrong stage in the pipeline, which has been corrected.
(merge 7735d7eee3 bc/sign-commit-with-custom-encoding later to maint).
* Further update to the i18n alias support to avoid regressions.
* "git fetch --deepen=<n>" in a full clone truncated the history to <n>
commits deep, which has been corrected to be a no-op instead.
(merge 2431f5e0e5 sp/shallow-deepen-on-non-shallow-repo-fix later to maint).
* "git maintenance" that goes background did not use the lockfile to
prevent multiple maintenance processes from running at the same
time, which has been corrected.
(merge 29364f1624 ps/maintenance-daemonize-lockfix later to maint).
* Remove ineffective strbuf presizing that would have computed an
allocation that would not have fit in the available memory anyway,
or too small due to integer wraparound to cause immediate automatic
growing.
(merge a9ce8526dc jk/pretty-no-strbuf-presizing later to maint).
* The HTTP walker misinterpreted the alternates file that gives an
absolute path when the server URL does not have the final slash
(i.e., "https://example.com" not "https://example.com/").
(merge b92387cd55 jk/dumb-http-alternate-fix later to maint).
* "git bisect" now uses the selected terms (e.g., old/new) more
consistently in its output.
(merge cb55991825 jr/bisect-custom-terms-in-output later to maint).
* Update GitLab CI jobs that exercise macOS.
(merge 62319b49bb ps/gitlab-ci-macOS-improvements later to maint).
* "Friday noon" asked in the morning on Sunday was parsed to be one
day before the specified time, which has been corrected.
(merge b809304101 ta/approxidate-noon-fix later to maint).
* The GIT_WORK_TREE variable prepared to invoke the push-to-checkout
hook was leaking into the environment even when there was no hook
used and broke the default push-to-deploy (i.e., let "git checkout"
update the working tree only when the working tree is clean).
(merge 44d04e4426 ar/receive-pack-worktree-env later to maint).
* A batch of documentation pages has been updated to use the modern
synopsis style.
(merge 2ef248ae45 ja/doc-synopsis-style-again later to maint).
* The "promisor.quiet" configuration variable was not used from
relevant submodules when commands like "grep --recurse-submodules"
triggered a lazy fetch, which has been corrected.
(merge fa1468a1f7 th/promisor-quiet-per-repo later to maint).
* Correct use of sockaddr API in "git daemon".
(merge 422a5bf575 st/daemon-sockaddr-fixes later to maint).
* A memory leak in `fetch_and_setup_pack_index()` when verification of
the downloaded pack index fails has been plugged. Also an obsolete
`unlink()` call on parse failure has been cleaned up.
* In t3070-wildmatch, "via ls-files" test variants with patterns
containing backslash escapes are now skipped on Windows, avoiding 36
test failures caused by pathspec separator conversion.
(merge 8c84e6802c kk/wildmatch-windows-ls-files-prereq later to maint).
* A linker warning on macOS when building with Xcode 16.3 or newer has
been avoided by passing -fno-common to the compiler when a
sufficiently new linker is detected.
(merge 5cd4d0d850 hn/macos-linker-warning later to maint).
* Documentation and tests have been added to clarify that Git's internal
raw timestamp format requires a `@` prefix for values less than
100,000,000 to prevent ambiguity with other formats like YYYYMMDD.
(merge 4018dc29ee ls/doc-raw-timestamp-prefix later to maint).
* Wording used in "format-patch --subject-prefix" documentation
has been improved.
(merge 4a1eb9304a lo/doc-format-patch-subject-prefix later to maint).
* Advanced emulation of kill() used on Windows in GfW has been
upstreamed to improve the symptoms like left-behind .lock files and
that fails to let the child clean-up itself when it gets killed.
(merge 363f1d8b3a js/win-kill-child-more-gently later to maint).
* The 'git describe --contains --all' command has been fixed to
properly honor the '--match' and '--exclude' options by passing
them down to 'git name-rev' with the appropriate reference
prefixes.
(merge 1891707d1b jk/describe-contains-all-match-fix later to maint).
* Various typos, grammatical errors, and duplicated words in both
documentation and code comments have been corrected.
(merge dc6068df67 wy/docs-typofixes later to maint).
* The subprocess handshake during startup has been made gentler by using
packet_read_line_gently() instead of packet_read_line() to prevent the
parent Git process from dying abruptly when a configured subprocess
(e.g., a clean/smudge filter) fails to start.
(merge 061a68e443 mm/subprocess-handshake-fix later to maint).
* The TSAN race in transfer_debug() within transport-helper.c has been
resolved by initializing the debug flag early in
bidirectional_transfer_loop() before spawning worker threads, allowing
the removal of a TSAN suppression.
(merge 85704eda18 ps/transport-helper-tsan-fix later to maint).
* 'git describe' has been taught to pass the 'refs/tags/' prefix down to
the ref iterator when '--all' is not requested, avoiding unnecessary
iteration over non-tag refs.
(merge 55088ac8a4 td/describe-tag-iteration later to maint).
* compute_reachable_generation_numbers() in commit-graph used a 32-bit
integer to accumulate parent generations, which is OK for generation
number v1 (topological levels), but with generation number v2
(adjusted committer timestamps), it truncated timestamps beyond
2106. Fixed by widening the accumulator to timestamp_t.
(merge fbcc5408fc en/commit-graph-timestamp-fix later to maint).
* Other code cleanup, docfix, build fix, etc.
(merge 80f4b802e9 ja/doc-difftool-synopsis-style later to maint).
(merge b96490241e jc/doc-timestamps-in-stat later to maint).
(merge ef85286e51 ss/t7004-unhide-git-failures later to maint).
(merge 7584d10bc2 mf/format-patch-cover-letter-format-docfix later to maint).
(merge 8547908eb3 pw/rename-to-get-current-worktree later to maint).
(merge 890229b3f3 sg/t6112-unwanted-tilde-expansion-fix later to maint).
(merge ab9753e7bc kh/doc-restore-double-underscores-fix later to maint).
(merge 4a9e097228 za/t2000-modernise-more later to maint).
(merge b635fd0725 kh/doc-log-decorate-list later to maint).
(merge 65ea197dca jk/commit-sign-overflow-fix later to maint).
(merge 3ccb16052a jk/apply-leakfix later to maint).
(merge 5e6e8dc786 tb/pseudo-merge-bugfixes later to maint).
(merge 6d09e798bc pb/doc-diff-format-updates later to maint).
(merge 34a891a2d3 rs/trailer-fold-optim later to maint).
(merge 499f9048e0 ps/t3903-cover-stash-include-untracked later to maint).
(merge b56ab270aa jk/sq-dequote-cleanup later to maint).
(merge 29d9fdcf10 rs/use-builtin-add-overflow-explicitly-on-clang later to maint).
(merge d9982e8290 ed/check-connected-close-err-fd-2.53 later to maint).
(merge 1740cc35d0 ed/check-connected-close-err-fd later to maint).
(merge f4d7eb3d1c sp/doc-range-diff-takes-notes later to maint).
(merge 83e7f3bd2b kh/free-commit-list later to maint).
(merge d1b72b29e9 am/doc-tech-hash-typofix later to maint).
(merge 014c454799 ak/typofixes later to maint).
(merge 522ea8ef7d js/osxkeychain-build-wo-rust later to maint).
(merge e8f12e0e95 jc/t1400-fifo-cleanup later to maint).
(merge 0bf506efd4 kw/gitattributes-typofix later to maint).
----------------------------------------------------------------
Changes since v2.54.0 are as follows:
Abhinav Gupta (2):
rebase: ignore non-branch update-refs
sequencer: remove todo_add_branch_context.commit
Adam Johnson (1):
stash: reuse cached index entries in --patch temporary index
Adrian Ratiu (9):
repository: fix repo_init() memleak due to missing _clear()
config: add a repo_config_get_uint() helper
hook: parse the hook.jobs config
hook: allow pre-push parallel execution
hook: add per-event jobs config
hook: warn when hook.<friendly-name>.jobs is set
hook: move is_known_hook() to hook.c for wider use
hook: add hook.<event>.enabled switch
hook: allow hook.jobs=-1 to use all available CPU cores
Aindriú Mac Giolla Eoin (1):
l10n: ga.po: update for Git 2.55
Alexander Monakov (1):
doc: fix typo in GIT_ALTERNATE_OBJECT_DIRECTORIES
Alexander Shopov (1):
l10n: bg.po: Updated Bulgarian translation (6322t)
Aliwoto (1):
http: reject unsupported proxy URL schemes
Alyssa Ross (1):
receive-pack: fix updateInstead with core.worktree
Andrew Kreimer (1):
doc: fix typos via codespell
Arijit Banerjee (1):
index-pack: retain child bases in delta cache
Arkadii Yakovets (1):
l10n: uk: add 2.55 translation
Bagas Sanjaya (1):
l10n: po-id for 2.55
Christian Couder (10):
promisor-remote: try accepted remotes before others in get_direct()
promisor-remote: pass config entry to all_fields_match() directly
promisor-remote: clarify that a remote is ignored
promisor-remote: reject empty name or URL in advertised remote
promisor-remote: refactor should_accept_remote() control flow
promisor-remote: refactor has_control_char()
promisor-remote: refactor accept_from_server()
promisor-remote: keep accepted promisor_info structs alive
promisor-remote: remove the 'accepted' strvec
t5710: use proper file:// URIs for absolute paths
D. Ben Knoble (1):
ignore: note info/exclude lives in GIT_COMMON_DIR, not GIT_DIR
David Lin (1):
cache-tree: fix inverted object existence check in cache_tree_fully_valid
Derrick Stolee (20):
t5516: fix test order flakiness
fetch: add --negotiation-restrict option
transport: rename negotiation_tips
remote: add remote.*.negotiationRestrict config
negotiator: add have_sent() interface
fetch: add --negotiation-include option for negotiation
remote: add remote.*.negotiationInclude config
send-pack: pass negotiation config in push
t5620: make test work with path-walk var
pack-objects: pass --objects with --path-walk
t/perf: add pack-objects filter and path-walk benchmark
path-walk: always emit directly-requested objects
path-walk: support blobless filter
backfill: die on incompatible filter options
path-walk: support blob size limit filter
path-walk: add pl_sparse_trees to control tree pruning
pack-objects: support sparse:oid filter with path-walk
t6601: tag otherwise-unreachable trees
t1092: test 'git restore' with sparse index
restore: avoid sparse index expansion
Dominik Loidolt (3):
compat/posix.h: enable UNUSED warning messages for Clang
compat/posix.h: clean up GIT_GNUC_PREREQ() and UNUSED
compat/posix.h: simplify GIT_GNUC_PREREQ() comparison
Elijah Newren (10):
backfill: reject rev-list arguments that do not make sense
backfill: document acceptance of revision-range in more standard manner
backfill: default to grabbing edge blobs too
diff: fix out-of-bounds reads and NULL deref in diffstat UTF-8 truncation
merge-ort: handle cached rename & trivial resolution interaction better
promisor-remote: document caller filtering contract
patch-ids.h: add missing trailing parenthesis in documentation comment
builtin/log: prefetch necessary blobs for `git cherry`
grep: prefetch necessary blobs
commit-graph: use timestamp_t for max parent generation accumulator
Emily Shaffer (3):
hook: allow parallel hook execution
hook: mark non-parallelizable hooks
hook: add -j/--jobs option to git hook run
Emir SARI (1):
l10n: tr: Update Turkish translations
Ethan Dickson (1):
connected: close err_fd in promisor fast-path
Ezekiel Newren (6):
xdiff/xdl_cleanup_records: delete local recs pointer
xdiff: use unambiguous types in xdl_bogo_sqrt()
xdiff/xdl_cleanup_records: use unambiguous types
xdiff/xdl_cleanup_records: make limits more clear
xdiff/xdl_cleanup_records: make setting action easier to follow
xdiff/xdl_cleanup_records: make execution of action easier to follow
Greg Hurrell (1):
git-jump: pick a mode automatically when invoked without arguments
Harald Nordgren (10):
stash: add --label-ours, --label-theirs, --label-base for apply
sequencer: allow create_autostash to run silently
sequencer: teach autostash apply to take optional conflict marker labels
checkout: rollback lock on early returns in merge_working_tree
checkout -m: autostash when switching branches
config.mak.uname: avoid macOS linker warning on Xcode 16.3+
config: add git_config_key_is_valid() for quiet validation
config: improve diagnostic for "set" with missing value
git-gui: silence install recipes under "make -s"
config.mak.uname: avoid macOS dup-library warning
Ivan Baluta (1):
doc: clarify push.default=simple behavior
Jacob Keller (1):
describe: fix --exclude, --match with --contains and --all
Jayesh Daga (1):
unpack-trees: use repository from index instead of global
Jean-Noël Avila (12):
doc: convert git-difftool manual page to synopsis style
doc: convert git-range-diff manual page to synopsis style
doc: convert git-shortlog manual page to synopsis style
doc: convert git-describe manual page to synopsis style
doc: convert git-bisect to synopsis style
doc: git bisect: clarify the usage of the synopsis vs actual command
doc: convert git-grep synopsis and options to new style
doc: convert git-am synopsis and options to new style
doc: convert git-apply synopsis and options to new style
doc: convert git-imap-send synopsis and options to new style
l10n: fr: version 2.55
l10n: fr: mass fix of typos
Jeff King (14):
t1800: test SIGPIPE with parallel hooks
Revert "transport-helper, connect: use clean_on_exit to reap children on abnormal exit"
pretty: drop strbuf pre-sizing from add_rfc2047()
http: handle absolute-path alternates from server root
apply: plug leak on "patch too large" error
commit: handle large commit messages in utf8 verification
quote.h: bump strvec forward declaration to the top
quote: drop sq_dequote_to_argv()
quote: simplify internals of dequoting
connect: use "service" enum for "name" argument
commit: fall back to full read when maybe_tree is NULL
transport-helper: fix typo in BUG() message
t/lib-httpd: bump apache timeout
t5551: put many-tags case into its own repo
Jiang Xin (1):
l10n: AGENTS.md: add quotation mark preservation guidelines
Johannes Schindelin (49):
sideband: mask control characters
sideband: introduce an "escape hatch" to allow control characters
sideband: do allow ANSI color sequences by default
sideband: add options to allow more control sequences to be passed through
sideband: offer to configure sanitizing on a per-URL basis
test-lib: allow bare repository access when breaking changes are enabled
t7900: do not let `$HOME/.gitconfig` interfere with XDG tests
t1300: remove global config settings injected by test-lib.sh
t1305: use `--git-dir=.` for bare repo in include cycle test
t5601: restore `.gitconfig` after includeIf test
ls-files tests: filter `.gitconfig` from `--others` output
status tests: filter `.gitconfig` from status output
safe.bareRepository: default to "explicit" with WITH_BREAKING_CHANGES
t5564: use a short path for the SOCKS proxy socket
ci: bump microsoft/setup-msbuild from v2 to v3
ci: bump actions/{upload,download}-artifact to v7 and v8
ci: bump actions/github-script from v8 to v9
ci: bump actions/checkout from v5 to v6
ci: bump git-for-windows/setup-git-for-windows-sdk from v1 to v2
l10n: bump mshick/add-pr-comment from v2 to v3
mingw: optionally use legacy (non-POSIX) delete semantics
maintenance(geometric): do release the `.idx` files before repacking
mingw: stop using nedmalloc
mingw: drop the build-system plumbing for nedmalloc
mingw: remove the vendored compat/nedmalloc/ subtree
index-pack, unpack-objects: use size_t for object size
git-zlib: handle data streams larger than 4GB
odb, packfile: use size_t for streaming object sizes
delta, packfile: use size_t for delta header sizes
test-tool: add a helper to synthesize large packfiles
t5608: add regression test for >4GB object clone
test-tool synthesize: use the unsafe hash for speed
test-tool synthesize: precompute pack for 4 GiB + 1
test-tool synthesize: add precomputed SHA-256 pack for 4 GiB + 1
t5608: mark >4GB tests as EXPENSIVE
ci: run expensive tests on push builds to integration branches
mingw: kill child processes in a gentler way
mingw: really handle SIGINT
compat/msvc: use _chsize_s for ftruncate
patch-delta: use size_t for sizes
pack-objects(check_pack_inflate()): use size_t instead of unsigned long
packfile: widen unpack_entry()'s size out-parameter to size_t
pack-objects: use size_t for in-core object sizes
packfile,delta: drop the `cast_size_t_to_ulong()` wrappers
odb: use size_t for object_info.sizep and the size APIs
osxkeychain: fix build with Rust
zlib: properly clamp to uLong
win32: ensure that `localtime_r()` is declared even in i686 builds
http: accept https:// proxies again
Johannes Sixt (2):
userdiff: tighten word-diff test case of the scheme driver
git-gui: remove unnecessary 'cd $_gitworktree' from do_gitk
Jonas Rebmann (3):
bisect: use selected alternate terms in status output
bisect: print bisect terms in single quotes
rev-parse: use selected alternate terms to look up refs
Jonatan Holmgren (1):
alias: restore support for simple dotted aliases
Junio C Hamano (30):
sideband: drop 'default' configuration
CodingGuidelines: st_mtimespec vs st_mtim vs st_mtime
t5551: "GIT_TEST_LONG=Yes make test" is broken
ci: enable EXPENSIVE for contributor builds
Start 2.55 cycle
The second batch
The 3rd batch
The 4th batch
The 5th batch
The 6th batch
Start preparing for 2.54.1
The 7th batch
The 8th batch
SubmittingPatches: proactively monitor GHCI pages
The 9th batch
The 10th batch
The 11th batch
SubmittingPatches: separate typofixes section
SubmittingPatches: describe cover letter
The 12th batch
The 13th batch
Git 2.55-rc0
t1400: have fifo test clean after itself
topic flush before -rc1 (batch 1)
topic flush before -rc1 (batch 2)
Git 2.55-rc1
Hopefully final batch before -rc2
A few more topics before -rc2
Git 2.55-rc2
Git 2.55
Justin Tobler (7):
odb: split `struct odb_transaction` into separate header
odb/transaction: use pluggable `begin_transaction()`
odb: update `struct odb_write_stream` read() callback
object-file: remove flags from transaction packfile writes
object-file: avoid fd seekback by checking object size upfront
object-file: generalize packfile writes to use odb_write_stream
odb/transaction: make `write_object_stream()` pluggable
Karthik Nayak (10):
refs: remove unused typedef 'ref_transaction_commit_fn'
refs: introduce `ref_store_init_options`
refs: extract out reflog config to generic layer
refs: return `ref_transaction_error` from `ref_transaction_update()`
update-ref: move `print_rejected_refs()` up
update-ref: handle rejections while adding updates
refs: move object parsing to the generic layer
refs: add peeled object ID to the `ref_update` struct
refs: use peeled tag values in reference backends
refs/files: skip lock files during consistency checks
Koutian Wu (1):
gitattributes: fix eol attribute for Perl scripts
Kristofer Karlsson (13):
commit-reach: introduce merge_base_flags enum
commit-reach: early exit paint_down_to_common for single merge-base
merge: use repo_in_merge_bases for octopus up-to-date check
revision: use priority queue in limit_list()
commit-reach: use object flags for tips_reachable_from_bases()
t6600: add tests for duplicate tips in tips_reachable_from_bases()
object.h: fix stale entries in object flag allocation table
commit-reach: deduplicate queue entries in paint_down_to_common
commit-reach: replace queue_has_nonstale() scan with O(1) tracking
pack-objects: call release_revisions() after cruft traversal
revision: introduce rev_walk_mode to clarify get_revision_1()
revision: use priority queue for non-limited streaming walks
t3070: skip ls-files tests with backslash patterns on Windows
Kristoffer Haugsbakk (15):
doc: log: fix --decorate description list
doc: log: use the same delimiter in description list
doc: restore: remove double underscore
doc: add caveat about turning off commit-graph
name-rev: wrap both blocks in braces
name-rev: run clang-format before factoring code
name-rev: factor code for sharing with a new command
name-rev: make dedicated --annotate-stdin --name-only test
format-rev: introduce builtin for on-demand pretty formatting
doc: hook: remove stray backtick
doc: hook: consistently capitalize Git
doc: config: include existing git-hook(1) section
doc: hook: don’t self-link via config include
*: replace deprecated free_commit_list
commit: remove deprecated functions
LorenzoPegorari (2):
http: cleanup function fetch_and_setup_pack_index()
http: fix memory leak in fetch_and_setup_pack_index()
Lucas Seiki Oshiro (1):
Documentation: remove redundant 'instead' in --subject-prefix
Lumynous (1):
l10n: zh-TW.po: Update Chinese (Traditional) translation
Luna Schwalbe (1):
doc: document and test `@` prefix for raw timestamps
Mark Levedahl (11):
git-gui: use HEAD as current branch when detached
git-gui: guard set/unset of GIT_DIR and GIT_WORK_TREE
git-gui: do not change global vars in choose_repository::pick
git-gui: use --absolute-git-dir
git-gui: use rev-parse exclusively to find a repository
git-gui: use git rev-parse for worktree discovery
git-gui: simplify [is_bare] to report if a worktree is known
git-gui: try harder to find worktree from gitdir
git-gui: allow specifying path '.' to the browser
git-gui: check browser/blame arguments carefully
git-gui: add gui and pick as explicit subcommands
Matheus Afonso Martins Moreira (8):
connect: rename enum protocol to url_scheme
url: move url_is_local_not_ssh to url.h
url: move scheme detection to URL header/source
url: return URL_SCHEME_UNKNOWN instead of dying
urlmatch: define url_parse function
builtin: create url-parse command
doc: describe the url-parse builtin
t9904: add tests for the new url-parse builtin
Matteo Beniamino (1):
l10n: it: fix italian usage messages alignment
Matthew John Cheetham (4):
http: extract http_reauth_prepare() from retry paths
http: attempt Negotiate auth in http.emptyAuth=auto mode
t5563: add tests for http.emptyAuth with Negotiate
doc: clarify http.emptyAuth values
Michael Montalbo (9):
diff: reject negative values for --inter-hunk-context
diff: reject negative values for -U/--unified
xdiff: guard against negative context lengths
parse-options: clarify what "negated" means for PARSE_OPT_NONEG
doc: clarify that --word-diff operates on line-level hunks
revision: move -L setup before output_format-to-diff derivation
line-log: integrate -L output with the standard log-tree pipeline
line-log: allow non-patch diff formats with -L
sub-process: use gentle handshake to avoid die() on startup failure
Mikel Forcada (1):
l10n: ca.po: update Catalan translation
Mirko Faina (3):
Fix docs for format.commitListFormat
revision.c: implement --max-count-oldest
bash-completions: add --max-count-oldest
Olamide Caleb Bello (8):
environment: move "trust_ctime" into `struct repo_config_values`
environment: move "check_stat" into `struct repo_config_values`
environment: move `zlib_compression_level` into `struct repo_config_values`
environment: move "pack_compression_level" into `struct repo_config_values`
environment: move "precomposed_unicode" into `struct repo_config_values`
environment: move "core_sparse_checkout_cone" into `struct repo_config_values`
environment: move "sparse_expect_files_outside_of_patterns" into `struct repo_config_values`
environment: move "warn_on_object_refname_ambiguity" into `struct repo_config_values`
Pablo Sabater (3):
graph: limit the graph width to a hard-coded max
graph: add --graph-lane-limit option
graph: add truncation mark to capped lanes
Patrick Steinhardt (91):
t: prepare `test_match_signal ()` calls for `set -e`
t: prepare `test_must_fail ()` for `set -e`
t: prepare `stop_git_daemon ()` for `set -e`
t: prepare `git config --unset` calls for `set -e`
t: prepare conditional test execution for `set -e`
t: prepare execution of potentially failing commands for `set -e`
t: prepare `test_when_finished ()`/`test_atexit()` for `set -e`
t0008: silence error in subshell when using `grep -v`
t1301: don't fail in case setfacl(1) doesn't exist or fails
t6002: fix use of `expr` with `set -e`
t9902: fix use of `read` with `set -e`
t: detect errors outside of test cases
replay: allow callers to control what happens with empty commits
builtin/history: generalize function to commit trees
builtin/history: introduce "fixup" subcommand
build: tolerate use of _Generic from glibc 2.43 with Clang
builtin/maintenance: fix locking with "--detach"
run-command: honor "gc.auto" for auto-maintenance
odb: introduce "in-memory" source
odb/source-inmemory: implement `free()` callback
odb: fix unnecessary call to `find_cached_object()`
odb/source-inmemory: implement `read_object_info()` callback
odb/source-inmemory: implement `read_object_stream()` callback
odb/source-inmemory: implement `write_object()` callback
odb/source-inmemory: implement `write_object_stream()` callback
cbtree: allow using arbitrary wrapper structures for nodes
oidtree: add ability to store data
odb/source-inmemory: convert to use oidtree
odb/source-inmemory: implement `for_each_object()` callback
odb/source-inmemory: implement `find_abbrev_len()` callback
odb/source-inmemory: implement `count_objects()` callback
odb/source-inmemory: implement `freshen_object()` callback
odb/source-inmemory: stub out remaining functions
odb: generic in-memory source
t/unit-tests: add tests for the in-memory object source
setup: replace use of `the_repository` in static functions
setup: stop using `the_repository` in `is_inside_git_dir()`
setup: stop using `the_repository` in `is_inside_work_tree()`
setup: stop using `the_repository` in `prefix_path()`
setup: stop using `the_repository` in `path_inside_repo()`
setup: stop using `the_repository` in `verify_filename()`
setup: stop using `the_repository` in `verify_non_filename()`
setup: stop using `the_repository` in `enter_repo()`
setup: stop using `the_repository` in `setup_work_tree()`
setup: stop using `the_repository` in `set_git_work_tree()`
setup: stop using `the_repository` in `setup_git_env()`
setup: stop using `the_repository` in `setup_git_directory_gently()`
setup: stop using `the_repository` in `setup_git_directory()`
setup: stop using `the_repository` in `upgrade_repository_format()`
setup: stop using `the_repository` in `check_repository_format()`
setup: stop using `the_repository` in `initialize_repository_version()`
setup: stop using `the_repository` in `create_reference_database()`
setup: stop using `the_repository` in `init_db()`
gitlab-ci: upgrade macOS runners
gitlab-ci: update macOS image
odb/source-loose: move loose source into "odb/" subsystem
odb/source-loose: store pointer to "files" instead of generic source
odb/source-loose: start converting to a proper `struct odb_source`
odb/source-loose: wire up `reprepare()` callback
odb/source-loose: wire up `close()` callback
odb/source-loose: wire up `read_object_info()` callback
odb/source-loose: wire up `read_object_stream()` callback
odb/source-loose: wire up `for_each_object()` callback
odb/source-loose: wire up `find_abbrev_len()` callback
odb/source-loose: wire up `count_objects()` callback
odb/source-loose: drop `odb_source_loose_has_object()`
odb/source-loose: wire up `freshen_object()` callback
loose: refactor object map to operate on `struct odb_source_loose`
odb/source-loose: wire up `write_object()` callback
object-file: refactor writing objects to use loose source
odb/source-loose: wire up `write_object_stream()` callback
odb/source-loose: stub out remaining callbacks
odb/source-loose: drop pointer to the "files" source
gitlab-ci: rearrange Linux jobs to match GitHub's order
gitlab-ci: add missing Linux jobs
ci: unify Linux images across GitLab and GitHub
t7527: fix broken TAP output
t7810: turn MB_REGEX check into a lazy prereq
t/test-lib: silence EBUSY errors on Windows during test cleanup
t/lib-git-p4: silence output when killing p4d and its watchdog
t: let prove fail when parsing invalid TAP output
t0001: plug test gaps for git-init(1) with GIT_OBJECT_DIRECTORY
setup: drop `setup_git_env()`
setup: deduplicate logic to apply repository format
repository: stop initializing the object database in `repo_set_gitdir()`
setup: stop creating the object database in `setup_git_env()`
setup: stop initializing object database without repository
repository: stop reading loose object map twice on repo init
setup: construct object database in `apply_repository_format()`
gitlab-ci: migrate Windows builds away from Chocolatey
t4216: fix no-op test that breaks TAP output
Paul Tarjan (13):
t9210, t9211: disable GIT_TEST_SPLIT_INDEX for scalar clone tests
fsmonitor: fix khash memory leak in do_handle_client
fsmonitor: fix hashmap memory leak in fsmonitor_run_daemon
compat/win32: add pthread_cond_timedwait
fsmonitor: use pthread_cond_timedwait for cookie wait
fsmonitor: rename fsm-ipc-darwin.c to fsm-ipc-unix.c
fsmonitor: rename fsm-settings-darwin.c to fsm-settings-unix.c
fsmonitor: implement filesystem change listener for Linux
run-command: add close_fd_above_stderr option
fsmonitor: close inherited file descriptors and detach in daemon
fsmonitor: add timeout to daemon stop command
fsmonitor: add tests for Linux
fsmonitor: convert shown khash to strset in do_handle_client
Peter Krefting (1):
l10n: sv.po: Update Swedish translation
Philippe Blain (3):
diff-format.adoc: remove mention of diff-tree specific output
diff-format.adoc: 'git diff-files' prints two lines for unmerged files
diff-format.adoc: mode and hash are 0* for unmerged paths from index only
Phillip Wood (5):
worktree: rename get_worktree_from_repository()
xdiff: reduce size of action arrays
xdiff: cleanup xdl_clean_mmatch()
xprepare: simplify error handling
xdiff: reduce the size of array
Pushkar Singh (2):
stash: add coverage for show --include-untracked
transport-helper: fix TSAN race in transfer_debug()
René Scharfe (10):
grep: fix --column --only-match for 2nd and later matches
sideband: clear full line when printing remote messages
strbuf: add strbuf_add_uint()
cat-file: use strbuf_add_uint()
ls-files: use strbuf_add_uint()
ls-tree: use strbuf_add_uint()
hex: add and use strbuf_add_oid_hex()
trailer: change strbuf in-place in unfold_value()
strbuf: use st_add3() in strbuf_grow()
use __builtin_add_overflow() in st_add() with Clang
Rob McDonald (1):
gitk: add horizontal scrollbar to the commit list pane
SZEDER Gábor (1):
t6112: avoid tilde expansion
Saagar Jha (1):
submodule-config: fix reading submodule.fetchJobs
Samo Pogačnik (1):
shallow: fix relative deepen on non-shallow repositories
Scott Bauersfeld (1):
index-pack, unpack-objects: increase input buffer from 4 KiB to 128 KiB
Scott L. Burson (1):
userdiff: extend Scheme support to cover other Lisp dialects
Sebastien Tardif (3):
daemon: fix IPv6 address corruption in lookup_hostname()
daemon: fix IPv6 address truncation in ip2str()
daemon: guard NULL REMOTE_PORT in execute() logging
Shreyansh Paliwal (3):
refs: add struct repository parameter in get_files_ref_lock_timeout_ms()
refs: remove the_hash_algo global state
refs/reftable-backend: drop uses of the_repository
Siddh Raman Pant (1):
Documentation/git-range-diff: add missing notes options in synopsis
Siddharth Asthana (1):
cat-file: add mailmap subcommand to --batch-command
Siddharth Shrimali (3):
t7004: drop hardcoded tag count for state verification
t7004: dynamically grab expected state in tests
t7004: avoid subshells to capture git exit codes
Tamir Duberstein (2):
describe: limit default ref iteration to tags
ls-files: filter pathspec before lstat
Taylor Blau (36):
t/helper: add 'test-tool bitmap write' subcommand
t5333: demonstrate various pseudo-merge bugs
pack-bitmap-write: sort pseudo-merge commit lookup table in pack order
pack-bitmap: fix inverted binary search in `pseudo_merge_at()`
pack-bitmap: fix pseudo-merge lookup for shared commits
pack-bitmap: parse commits in `find_pseudo_merge_group_for_ref()`
pack-bitmap: reject pseudo-merge "sampleRate" of 0
Documentation: fix broken `sampleRate` in gitpacking(7)
pack-bitmap: prevent pattern leak on pseudo-merge re-assignment
midx-write: handle noop writes when converting incremental chains
midx: use `strset` for retained MIDX files
midx: build `keep_hashes` array in order
midx: use `strvec` for `keep_hashes`
midx: introduce `--no-write-chain-file` for incremental MIDX writes
midx: support custom `--base` for incremental MIDX writes
repack: track the ODB source via existing_packs
midx: expose `midx_layer_contains_pack()`
repack-midx: factor out `repack_prepare_midx_command()`
repack-midx: extract `repack_fill_midx_stdin_packs()`
repack-geometry: prepare for incremental MIDX repacking
builtin/repack.c: convert `--write-midx` to an `OPT_CALLBACK`
packfile: ensure `close_pack_revindex()` frees in-memory revindex
repack: implement incremental MIDX repacking
repack: introduce `--write-midx=incremental`
repack: allow `--write-midx=incremental` without `--geometric`
path-walk: support `tree:0` filter
path-walk: support `object:type` filter
path-walk: support `combine` filter
pack-bitmap: pass object position to `fill_bitmap_tree()`
pack-bitmap: check subtree bits before recursing
pack-bitmap: reuse stored selected bitmaps
pack-bitmap: consolidate `find_object_pos()` success path
pack-bitmap: cache object positions during fill
pack-bitmap: sort bitmaps before XORing
pack-bitmap: remember pseudo-merge parents
pack-bitmap: build pseudo-merge bitmaps after regular bitmaps
Toon Claes (1):
generate-configlist: collapse depfile for older Ninja
Trieu Huynh (1):
promisor-remote: fix promisor.quiet to use the correct repository
Tuomas Ahola (8):
approxidate: make "today" wrap to midnight
t0006: add support for approxidate test date adjustment
approxidate: make "specials" respect fixed day-of-month
approxidate: use deferred mday adjustments for "specials"
docs: fix typos
doc: config: terminate runaway lists
doc: config/sideband: fix description list delimiter
doc: git-config: escape erroneous highlight markup
Usman Akinyemi (3):
remote: fix sign-compare warnings in push_cas_option
remote: move remote group resolution to remote.c
push: support pushing to a remote group
Weijie Yuan (1):
docs: fix typos and grammar
Zakariyah Ali (1):
t2000: consolidate second scenario into a single test block
brian m. carlson (6):
docs: update version with default Rust support
ci: install cargo on Alpine
Linux: link against libdl
Enable Rust by default
commit: name UTF-8 function appropriately
commit: sign commit after mutating buffer
lilydjwg (2):
l10n: TEAMS: change Simplified Chinese team leader
l10n: zh_CN: updated translation for 2.55
^ permalink raw reply
* Open to a DR60+ link exchange?
From: Mason Orantes @ 2026-06-29 17:01 UTC (permalink / raw)
To: git, git-security
Hi Team,
Hope you're doing well.
I wanted to ask if you're open to a direct link exchange.
I have access to DR60+ websites where I can place a relevant
contextual link for you. In exchange, I'd like a relevant link from
your site.
There is no fee involved. The only requirement is that both links
should be niche-relevant and placed naturally inside useful content.
If this works for you, I can share my domain list for review.
git-scm.com
Best,
Mason Orantes
Pixel Logic IT
^ permalink raw reply
* Re: [PATCH 2/6] odb: make backend-specific fields optional
From: Justin Tobler @ 2026-06-29 17:25 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <20260624-b4-pks-odb-drop-whence-v1-2-8d1877b790ac@pks.im>
On 26/06/24 02:19PM, Patrick Steinhardt wrote:
> The `struct object_info` carries two pieces of information
> about how an object was looked up:
>
> - The `whence` enum identifying the backend.
>
> - The backend-tagged union `u` exposing backend-specific details
> (currently only the packed-source case, which records the owning
> pack, offset and packed object type).
>
> The union is populated unconditionally, even though most callers don't
> care about provenance at all.
>
> Split the backend-specific union out into a new public type, `struct
> object_info_source`, and make the object info structure carry it via
> just another opt-in request pointer. As with all the other requestable
> information, callers that need source info allocate a `struct
> object_info_source` on the stack and point `sourcep` at it; callers that
> don't care about it simply leave the field as a `NULL` pointer. Adapt
> callers accordingly.
Since not all callers may require this information, requiring callers to
explicitly request it seems reasonable to me.
> Note that the `whence` enum is strictly-speaking also backend-specific
> information, so it would be another good candidate to be moved into the
> `struct object_info_source`. For now though it is left alone, as it will
> be replaced by a `struct odb_source` pointer in a subsequent commit.
>
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
> builtin/cat-file.c | 8 +++++--
> builtin/index-pack.c | 8 +++++--
> builtin/pack-objects.c | 15 +++++++++----
> odb.c | 3 ++-
> odb.h | 60 +++++++++++++++++++++++++++++++++-----------------
> packfile.c | 33 ++++++++++++++-------------
> reachable.c | 5 ++++-
> 7 files changed, 87 insertions(+), 45 deletions(-)
>
> diff --git a/builtin/cat-file.c b/builtin/cat-file.c
> index 8726485f1f..adc626ce30 100644
> --- a/builtin/cat-file.c
> +++ b/builtin/cat-file.c
> @@ -835,7 +835,8 @@ static int batch_one_object_oi(const struct object_id *oid,
> {
> struct for_each_object_payload *payload = _payload;
> if (oi && oi->whence == OI_PACKED)
> - return payload->callback(oid, oi->u.packed.pack, oi->u.packed.offset,
> + return payload->callback(oid, oi->sourcep->u.packed.pack,
> + oi->sourcep->u.packed.offset,
> payload->payload);
We update callsites now that object source info is stored differently in
`struct object_info`.
> return payload->callback(oid, NULL, 0, payload->payload);
> }
> @@ -906,7 +907,10 @@ static void batch_each_object(struct batch_options *opt,
> &payload, flags);
> }
> } else {
> - struct object_info oi = { 0 };
> + struct object_info_source oi_source;
> + struct object_info oi = {
> + .sourcep = &oi_source,
> + };
Caller that wish to know information regarding the source of the object
are required to explicitly request it. Makes sense.
[snip]
> struct object_info {
> /* Request */
> enum object_type *typep;
> @@ -269,32 +301,20 @@ struct object_info {
> */
> time_t *mtimep;
>
> + /*
> + * Backend-specific information that tells the caller where exactly an
> + * object was looked up from. This information should help disambiguate
> + * object lookups in case the same object exists in multiple sources,
> + * or multiple times in the same source.
> + */
> + struct object_info_source *sourcep;
To me, the name `sourcep` makes me think a pointer to `struct
odb_source`. This did confuse me slightly when initially reading, but
I'm not sure it's worth it to be overly verbose here.
[snip]
> diff --git a/packfile.c b/packfile.c
> index 2b741d7a76..688c410b35 100644
> --- a/packfile.c
> +++ b/packfile.c
> @@ -1422,22 +1422,25 @@ int packed_object_info_with_index_pos(struct odb_source_packed *source UNUSED,
> }
>
> oi->whence = OI_PACKED;
> - oi->u.packed.offset = obj_offset;
> - oi->u.packed.pack = p;
>
> - switch (type) {
> - case OBJ_NONE:
> - oi->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
> - break;
> - case OBJ_REF_DELTA:
> - oi->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
> - break;
> - case OBJ_OFS_DELTA:
> - oi->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
> - break;
> - default:
> - oi->u.packed.type = PACKED_OBJECT_TYPE_FULL;
> - break;
> + if (oi->sourcep) {
> + oi->sourcep->u.packed.offset = obj_offset;
> + oi->sourcep->u.packed.pack = p;
> +
> + switch (type) {
> + case OBJ_NONE:
> + oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
> + break;
> + case OBJ_REF_DELTA:
> + oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
> + break;
> + case OBJ_OFS_DELTA:
> + oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
> + break;
> + default:
> + oi->sourcep->u.packed.type = PACKED_OBJECT_TYPE_FULL;
> + break;
> + }
Source information is no longer unconditionally set.
Overall, this patch looks good.
-Justin
^ permalink raw reply
* Re: [PATCH v6 4/4] history: re-edit a squash with every message
From: Junio C Hamano @ 2026-06-29 17:38 UTC (permalink / raw)
To: Harald Nordgren; +Cc: Harald Nordgren via GitGitGadget, git
In-Reply-To: <xmqq7bnhz9jr.fsf@gitster.g>
Junio C Hamano <gitster@pobox.com> writes:
> Harald Nordgren <haraldnordgren@gmail.com> writes:
>
>>> I doubt it would make practical difference, but one thing I notice
>>> is that unlike "git rebase -i", this one does not intersperse
>>> markers like "# This is the 1st commit message" in between the
>>> messages taken from the squashed commits, so it is not exactly
>>> "mirroring".
>>
>> I wouldn't mind extracting that logic from 'rebase -i' to show it
>> here. It would be nice to have.
>
> If we can share more code (not necessarily the exact existing
> code---after cleaning it up if needed is perfectly fine and may even
> be better) across codebaes that would be excellent. Thanks.
After looking at what Phillip said in a side thread (look for "So
instead of ... We'd have") [*], I retract my "I doubt it would make
practical difference". Without boundary that shows where each
message begins, the result is much harder to look at.
[Reference]
* https://lore.kernel.org/git/3b3af3ef-a043-4af9-964e-429237789c97@gmail.com/
^ permalink raw reply
page: | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox