Git development
 help / color / mirror / Atom feed
* 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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox