]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
5 weeks agoupload-pack: fix debug statement when flushing packfile data
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:12 +0000 (07:45 +0100)] 
upload-pack: fix debug statement when flushing packfile data

When git-upload-pack(1) writes packfile data to the client we have some
logic in place that buffers some partial lines. When that buffer still
contains data after git-pack-objects(1) has finished we flush the buffer
so that all remaining bytes are sent out.

Curiously, when we do so we also print the string "flushed." to stderr.
This statement has been introduced in b1c71b7281 (upload-pack: avoid
sending an incomplete pack upon failure, 2006-06-20), so quite a while
ago. What's interesting though is that stderr is typically spliced
through to the client-side, and consequently the client would see this
message. Munging the way how we do the caching indeed confirms this:

  $ git clone file:///home/pks/Development/linux/
  Cloning into bare repository 'linux.git'...
  remote: Enumerating objects: 12980346, done.
  remote: Counting objects: 100% (131820/131820), done.
  remote: Compressing objects: 100% (50290/50290), done.
  remote: Total 12980346 (delta 96319), reused 104500 (delta 81217), pack-reused 12848526 (from 1)
  Receiving objects: 100% (12980346/12980346), 3.23 GiB | 57.44 MiB/s, done.
  flushed.
  Resolving deltas: 100% (10676718/10676718), done.

It's quite clear that this string shouldn't ever be visible to the
client, so it rather feels like this is a left-over debug statement. The
menitoned commit doesn't mention this line, either.

Remove the debug output to prepare for a change in how we do the
buffering in the next commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot0410: modernize delete_object helper
Siddharth Shrimali [Fri, 13 Mar 2026 05:31:59 +0000 (11:01 +0530)] 
t0410: modernize delete_object helper

The delete_object helper currently relies on a manual sed command to
calculate object paths. This works, but it's a bit brittle and forces
us to maintain shell logic that Git's own test suite can already
handle more elegantly.

Switch to 'test_oid_to_path' to let Git handle the path logic. This
makes the helper hash independent, which is much cleaner than manual
string manipulation. While at it, use 'local' to declare helper-specific
variables and quote them to follow Git's coding style. This prevents
them from leaking into global shell scope and avoids potential naming
conflicts with other parts of the test suite.

Helped-by: Pushkar Singh <pushkarkumarsingh1970@gmail.com>
Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agofast-import: add mode to sign commits with invalid signatures
Justin Tobler [Fri, 13 Mar 2026 01:39:38 +0000 (20:39 -0500)] 
fast-import: add mode to sign commits with invalid signatures

With git-fast-import(1), handling of signed commits is controlled via
the `--signed-commits=<mode>` option. When an invalid signature is
encountered, a user may want the option to sign the commit again as
opposed to just stripping the signature. To facilitate this, introduce a
"sign-if-invalid" mode for the `--signed-commits` option. Optionally, a
key ID may be explicitly provided in the form
`sign-if-invalid[=<keyid>]` to specify which signing key should be used
when signing invalid commit signatures.

Note that to properly support interoperability mode when signing commit
signatures, the commit buffer must be created in both the repository and
compatability object formats to generate the appropriate signatures
accordingly. As currently implemented, the commit buffer for the
compatability object format is not reconstructed and thus signing
commits in interoperability mode is not yet supported. Support may be
added in the future.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agogpg-interface: allow sign_buffer() to use default signing key
Justin Tobler [Fri, 13 Mar 2026 01:39:37 +0000 (20:39 -0500)] 
gpg-interface: allow sign_buffer() to use default signing key

The `sign_commit_to_strbuf()` helper in "commit.c" provides fallback
logic to get the default configured signing key when a key is not
provided and handles generating the commit signature accordingly. This
signing operation is not really specific to commits as any arbitrary
buffer can be signed. Also, in a subsequent commit, this same logic is
reused by git-fast-import(1) when signing commits with invalid
signatures.

Remove the `sign_commit_to_strbuf()` helper from "commit.c" and extend
`sign_buffer()` in "gpg-interface.c" to support using the default key as
a fallback when the `SIGN_BUFFER_USE_DEFAULT_KEY` flag is provided. Call
sites are updated accordingly.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agocommit: remove unused forward declaration
Justin Tobler [Fri, 13 Mar 2026 01:39:36 +0000 (20:39 -0500)] 
commit: remove unused forward declaration

In 6206089cbd (commit: write commits for both hashes, 2023-10-01),
`sign_with_header()` was removed, but its forward declaration in
"commit.h" was left. Remove the unused declaration.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agotransport-helper, connect: use clean_on_exit to reap children on abnormal exit
Andrew Au [Thu, 12 Mar 2026 21:49:37 +0000 (21:49 +0000)] 
transport-helper, connect: use clean_on_exit to reap children on abnormal exit

When a long-running service (e.g., a source indexer) runs as PID 1
inside a container and repeatedly spawns git, git may in turn spawn
child processes such as git-remote-https or ssh. If git exits abnormally
(e.g., via exit(128) on a transport error), the normal cleanup paths
(disconnect_helper, finish_connect) are bypassed, and these children are
never waited on. The children are reparented to PID 1, which does not
reap them, so they accumulate as zombies over time.

Set clean_on_exit and wait_after_clean on child_process structs in both
transport-helper.c and connect.c so that the existing run-command
cleanup infrastructure handles reaping on any exit path. This avoids
rolling custom atexit handlers that call finish_command(), which could
deadlock if the child is blocked waiting for the parent to close a pipe.

The clean_on_exit mechanism sends SIGTERM first, then waits, ensuring
the child terminates promptly. It also handles signal-based exits, not
just atexit.

Signed-off-by: Andrew Au <cshung@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoThe 16th batch
Junio C Hamano [Thu, 12 Mar 2026 21:08:20 +0000 (14:08 -0700)] 
The 16th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoMerge branch 'ps/odb-sources'
Junio C Hamano [Thu, 12 Mar 2026 21:09:06 +0000 (14:09 -0700)] 
Merge branch 'ps/odb-sources'

The object source API is getting restructured to allow plugging new
backends.

* ps/odb-sources:
  odb/source: make `begin_transaction()` function pluggable
  odb/source: make `write_alternate()` function pluggable
  odb/source: make `read_alternates()` function pluggable
  odb/source: make `write_object_stream()` function pluggable
  odb/source: make `write_object()` function pluggable
  odb/source: make `freshen_object()` function pluggable
  odb/source: make `for_each_object()` function pluggable
  odb/source: make `read_object_stream()` function pluggable
  odb/source: make `read_object_info()` function pluggable
  odb/source: make `close()` function pluggable
  odb/source: make `reprepare()` function pluggable
  odb/source: make `free()` function pluggable
  odb/source: introduce source type for robustness
  odb: move reparenting logic into respective subsystems
  odb: embed base source in the "files" backend
  odb: introduce "files" source
  odb: split `struct odb_source` into separate header

5 weeks agoMerge branch 'hn/status-compare-with-push'
Junio C Hamano [Thu, 12 Mar 2026 21:09:06 +0000 (14:09 -0700)] 
Merge branch 'hn/status-compare-with-push'

"git status" learned to show comparison between the current branch
and various other branches listed on status.compareBranches
configuration.

* hn/status-compare-with-push:
  status: clarify how status.compareBranches deduplicates
  status: add status.compareBranches config for multiple branch comparisons
  refactor format_branch_comparison in preparation

5 weeks agoMerge branch 'ds/for-each-repo-w-worktree'
Junio C Hamano [Thu, 12 Mar 2026 21:09:05 +0000 (14:09 -0700)] 
Merge branch 'ds/for-each-repo-w-worktree'

"git for-each-repo" started from a secondary worktree did not work
as expected, which has been corrected.

* ds/for-each-repo-w-worktree:
  for-each-repo: simplify passing of parameters
  for-each-repo: work correctly in a worktree
  run-command: extract sanitize_repo_env helper
  for-each-repo: test outside of repo context

5 weeks agoThe 15th batch
Junio C Hamano [Thu, 12 Mar 2026 17:55:41 +0000 (10:55 -0700)] 
The 15th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoMerge branch 'sp/send-email-validate-charset'
Junio C Hamano [Thu, 12 Mar 2026 17:56:05 +0000 (10:56 -0700)] 
Merge branch 'sp/send-email-validate-charset'

"git send-email" has learned to be a bit more careful when it
accepts charset to use from the end-user, to avoid 'y' (mistaken
'yes' when expecting a charset like 'UTF-8') and other nonsense.

* sp/send-email-validate-charset:
  send-email: validate charset name in 8bit encoding prompt

5 weeks agoMerge branch 'dt/send-email-client-cert'
Junio C Hamano [Thu, 12 Mar 2026 17:56:04 +0000 (10:56 -0700)] 
Merge branch 'dt/send-email-client-cert'

"git send-email" learns to support use of client-side certificates.

* dt/send-email-client-cert:
  send-email: add client certificate options

5 weeks agoMerge branch 'ps/ci-gitlab-prepare-for-macos-14-deprecation'
Junio C Hamano [Thu, 12 Mar 2026 17:56:04 +0000 (10:56 -0700)] 
Merge branch 'ps/ci-gitlab-prepare-for-macos-14-deprecation'

Move gitlab CI from macOS 14 images that are being deprecated.

* ps/ci-gitlab-prepare-for-macos-14-deprecation:
  gitlab-ci: update to macOS 15 images
  meson: detect broken iconv that requires ICONV_RESTART_RESET
  meson: simplify iconv-emits-BOM check

5 weeks agoMerge branch 'ag/send-email-sasl-with-host-port'
Junio C Hamano [Thu, 12 Mar 2026 17:56:04 +0000 (10:56 -0700)] 
Merge branch 'ag/send-email-sasl-with-host-port'

"git send-email" learns to pass hostname/port to Authen::SASL
module.

* ag/send-email-sasl-with-host-port:
  send-email: pass smtp hostname and port to Authen::SASL

5 weeks agoMerge branch 'ss/t9123-setup-inside-test-expect-success'
Junio C Hamano [Thu, 12 Mar 2026 17:56:04 +0000 (10:56 -0700)] 
Merge branch 'ss/t9123-setup-inside-test-expect-success'

Test clean-up.

* ss/t9123-setup-inside-test-expect-success:
  t9123: use test_when_finished for cleanup

5 weeks agoMerge branch 'sk/oidmap-clear-with-custom-free-func'
Junio C Hamano [Thu, 12 Mar 2026 17:56:04 +0000 (10:56 -0700)] 
Merge branch 'sk/oidmap-clear-with-custom-free-func'

A bit of OIDmap API enhancement and cleanup.

* sk/oidmap-clear-with-custom-free-func:
  builtin/rev-list: migrate missing_objects cleanup to oidmap_clear_with_free()
  oidmap: make entry cleanup explicit in oidmap_clear

5 weeks agoMerge branch 'jt/doc-submitting-patches-study-before-sending'
Junio C Hamano [Thu, 12 Mar 2026 17:56:03 +0000 (10:56 -0700)] 
Merge branch 'jt/doc-submitting-patches-study-before-sending'

Doc update for our contributors.

* jt/doc-submitting-patches-study-before-sending:
  Documentation: extend guidance for submitting patches

5 weeks agoMerge branch 'os/doc-custom-subcommand-on-path'
Junio C Hamano [Thu, 12 Mar 2026 17:56:03 +0000 (10:56 -0700)] 
Merge branch 'os/doc-custom-subcommand-on-path'

The way end-users can add their own "git <cmd>" subcommand by
storing "git-<cmd>" in a directory on their $PATH has not been
documented clearly, which has been corrected.

* os/doc-custom-subcommand-on-path:
  doc: add information regarding external commands

5 weeks agoMerge branch 'ss/t3700-modernize'
Junio C Hamano [Thu, 12 Mar 2026 17:56:03 +0000 (10:56 -0700)] 
Merge branch 'ss/t3700-modernize'

Test clean-up.

* ss/t3700-modernize:
  t3700: use test_grep helper for better diagnostics
  t3700: avoid suppressing git's exit code

5 weeks agoMerge branch 'lp/doc-gitprotocol-pack-fixes'
Junio C Hamano [Thu, 12 Mar 2026 17:56:03 +0000 (10:56 -0700)] 
Merge branch 'lp/doc-gitprotocol-pack-fixes'

Doc update.

* lp/doc-gitprotocol-pack-fixes:
  doc: gitprotocol-pack: normalize italic formatting
  doc: gitprotocol-pack: improve paragraphs structure
  doc: gitprotocol-pack: fix pronoun-antecedent agreement

5 weeks agoMerge branch 'kj/path-micro-code-cleanup'
Junio C Hamano [Thu, 12 Mar 2026 17:56:02 +0000 (10:56 -0700)] 
Merge branch 'kj/path-micro-code-cleanup'

Code clean-up.

* kj/path-micro-code-cleanup:
  path: remove redundant function calls
  path: use size_t for dir_prefix length
  path: remove unused header

5 weeks agoMerge branch 'bc/sha1-256-interop-02'
Junio C Hamano [Thu, 12 Mar 2026 17:56:02 +0000 (10:56 -0700)] 
Merge branch 'bc/sha1-256-interop-02'

The code to maintain mapping between object names in multiple hash
functions is being added, written in Rust.

* bc/sha1-256-interop-02:
  object-file-convert: always make sure object ID algo is valid
  rust: add a small wrapper around the hashfile code
  rust: add a new binary object map format
  rust: add functionality to hash an object
  rust: add a build.rs script for tests
  rust: fix linking binaries with cargo
  hash: expose hash context functions to Rust
  write-or-die: add an fsync component for the object map
  csum-file: define hashwrite's count as a uint32_t
  rust: add additional helpers for ObjectID
  hash: add a function to look up hash algo structs
  rust: add a hash algorithm abstraction
  rust: add a ObjectID struct
  hash: use uint32_t for object_id algorithm
  conversion: don't crash when no destination algo
  repository: require Rust support for interoperability

5 weeks agot9200: replace test -f with modern path helper
Pablo Sabater [Thu, 12 Mar 2026 17:33:05 +0000 (18:33 +0100)] 
t9200: replace test -f with modern path helper

Replace old style 'test -f' with helper
'test_path_is_file', which make debugging
a failing test easier by loudly reporting
what expectation was not met.

Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agobuiltin/mktree: remove USE_THE_REPOSITORY_VARIABLE
Tian Yuchen [Thu, 12 Mar 2026 16:42:03 +0000 (00:42 +0800)] 
builtin/mktree: remove USE_THE_REPOSITORY_VARIABLE

The 'cmd_mktree()' function already receives a 'struct repository *repo'
pointer, but it was previously marked as UNUSED.

Pass the 'repo' pointer down to 'mktree_line()' and 'write_tree()'.
Consequently, remove the 'USE_THE_REPOSITORY_VARIABLE' macro, replace
usages of 'the_repository', and swap 'parse_oid_hex()' with its context-aware
version 'parse_oid_hex_algop()'.

This refactoring is safe because 'cmd_mktree()' is registered with the
'RUN_SETUP' flag in 'git.c', which guarantees that the command is
executed within a initialized repository, ensuring that the passed 'repo'
pointer is never 'NULL'.

Signed-off-by: Tian Yuchen <cat@malon.dev>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoodb: introduce generic object counting
Patrick Steinhardt [Thu, 12 Mar 2026 08:43:01 +0000 (09:43 +0100)] 
odb: introduce generic object counting

Similar to the preceding commit, introduce counting of objects on the
object database level, replacing the logic that we have in
`repo_approximate_object_count()`.

Note that the function knows to cache the object count. It's unclear
whether this cache is really required as we shouldn't have that many
cases where we count objects repeatedly. But to be on the safe side the
caching mechanism is retained, with the only excepting being that we
also have to use the passed flags as caching key.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoodb/source: introduce generic object counting
Patrick Steinhardt [Thu, 12 Mar 2026 08:43:00 +0000 (09:43 +0100)] 
odb/source: introduce generic object counting

Introduce generic object counting on the object database source level
with a new backend-specific callback function.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoobject-file: generalize counting objects
Patrick Steinhardt [Thu, 12 Mar 2026 08:42:59 +0000 (09:42 +0100)] 
object-file: generalize counting objects

Generalize the function introduced in the preceding commit to not only
be able to approximate the number of loose objects, but to also provide
an accurate count. The behaviour can be toggled via a new flag.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoobject-file: extract logic to approximate object count
Patrick Steinhardt [Thu, 12 Mar 2026 08:42:58 +0000 (09:42 +0100)] 
object-file: extract logic to approximate object count

In "builtin/gc.c" we have some logic that checks whether we need to
repack objects. This is done by counting the number of objects that we
have and checking whether it exceeds a certain threshold. We don't
really need an accurate object count though, which is why we only
open a single object directory shard and then extrapolate from there.

Extract this logic into a new function that is owned by the loose object
database source. This is done to prepare for a subsequent change, where
we'll introduce object counting on the object database source level.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agopackfile: extract logic to count number of objects
Patrick Steinhardt [Thu, 12 Mar 2026 08:42:57 +0000 (09:42 +0100)] 
packfile: extract logic to count number of objects

In a subsequent commit we're about to introduce a new
`odb_source_count_objects()` function so that we can make the logic
pluggable. Prepare for this change by extracting the logic that we have
to count packed objects into a standalone function.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoodb: stop including "odb/source.h"
Patrick Steinhardt [Thu, 12 Mar 2026 08:42:56 +0000 (09:42 +0100)] 
odb: stop including "odb/source.h"

The "odb.h" header currently includes the "odb/source.h" file. This is
somewhat roundabout though: most callers shouldn't have to care about
the `struct odb_source`, but should rather use the ODB-level functions.
Furthermore, it means that a couple of definitions have to live on the
source level even though they should be part of the generic interface.

Reverse the relation between "odb/source.h" and "odb.h" and move the
enums and typedefs that relate to the generic interfaces back into
"odb.h". Add the necessary includes to all files that rely on the
transitive include.

Suggested-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agorun-command: wean auto_maintenance() functions off the_repository
Burak Kaan Karaçay [Thu, 12 Mar 2026 14:44:37 +0000 (17:44 +0300)] 
run-command: wean auto_maintenance() functions off the_repository

The prepare_auto_maintenance() relies on the_repository to read
configurations. Since run_auto_maintenance() calls
prepare_auto_maintenance(), it also implicitly depends the_repository.

Add 'struct repository *' as a parameter to both functions and update
all callers to pass the_repository.

With no global repository dependencies left in this file, remove the
USE_THE_REPOSITORY_VARIABLE macro.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agorun-command: wean start_command() off the_repository
Burak Kaan Karaçay [Thu, 12 Mar 2026 14:44:36 +0000 (17:44 +0300)] 
run-command: wean start_command() off the_repository

The start_command() relies on the_repository due to the
close_object_store flag in 'struct child_process'. When this flag is
set, start_command() closes the object store associated with
the_repository before spawning a child process.

To eliminate this dependency, replace the 'close_object_store' with the
new 'struct object_database *odb_to_close' field. This allows callers to
specify the object store that needs to be closed.

Suggested-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoimap-send: move common code into function host_matches()
Beat Bolli [Wed, 11 Mar 2026 22:10:27 +0000 (23:10 +0100)] 
imap-send: move common code into function host_matches()

Move the ASN1_STRING access, the associated cast and the check for
embedded NUL bytes into host_matches() to simplify both callers.

Reformulate the NUL check using memchr() and add a comment to make it
more obvious what it is about.

Signed-off-by: Beat Bolli <dev+git@drbeat.li>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoimap-send: use the OpenSSL API to access the subject common name
Beat Bolli [Wed, 11 Mar 2026 22:10:26 +0000 (23:10 +0100)] 
imap-send: use the OpenSSL API to access the subject common name

The OpenSSL 4.0 master branch has deprecated the
X509_NAME_get_text_by_NID function. Use the recommended replacement APIs
instead. They have existed since OpenSSL v1.1.0.

Take care to get the constness right for pre-4.0 versions.

Signed-off-by: Beat Bolli <dev+git@drbeat.li>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoimap-send: use the OpenSSL API to access the subject alternative names
Beat Bolli [Wed, 11 Mar 2026 22:10:25 +0000 (23:10 +0100)] 
imap-send: use the OpenSSL API to access the subject alternative names

The OpenSSL 4.0 master branch has made the ASN1_STRING structure opaque,
forbidding access to its internal fields. Use the official accessor
functions instead. They have existed since OpenSSL v1.1.0.

Signed-off-by: Beat Bolli <dev+git@drbeat.li>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot: allow use of "sed -E"
Junio C Hamano [Wed, 11 Mar 2026 21:35:41 +0000 (14:35 -0700)] 
t: allow use of "sed -E"

Since early 2019 with e62e225f (test-lint: only use only sed [-n]
[-e command] [-f command_file], 2019-01-20), we have been trying to
limit the options of "sed" we use in our tests to "-e <pattern>",
"-n", and "-f <file>".

Before the commit, we were trying to reject only "-i" (which is one
of the really-not-portable options), but the commit explicitly
wanted to reject use of "-E" (use ERE instead of BRE).  The commit
cites the then-current POSIX.1 (Issue 7, 2018 edition) to show that
"even recent POSIX does not have it!", but the latest edition (Issue
8) documents "-E" as an option to use ERE.

But that was 7 years ago, and that is a long time for many things to
happen.

Besides, we have been using "sed -E" without the check in question
triggering in one of the scripts since 2022, with 461fec41 (bisect
run: keep some of the post-v2.30.0 output, 2022-11-10).  It was
hidden because the 'E' was squished with another single letter
option.

t/t6030-bisect-porcelain.sh: sed -En 's/.*(bisect...

This escaped the rather simple pattern used in the checker

    /\bsed\s+-[^efn]\s+/ and err 'sed option not portable...';

because -E did not appear as a singleton.

Let's change the rule to allow the "-E" option, which nobody has
complained against for the past 3 years.  We rewrite our first use
of the "-E" option so that it is caught by the old rule, primarily
because we do not want to teach our mischievous developers how to
smuggle in an unwanted option undetected by the test lint.  And at
the same time, loosen the pattern to allow "-E" the same way we
allow "-n" and friends.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot9200: handle missing CVS with skip_all
Pablo Sabater [Wed, 11 Mar 2026 19:40:02 +0000 (20:40 +0100)] 
t9200: handle missing CVS with skip_all

CVS initialization runs outside a test_expect_success and when it
fails, the error report isn't good.

Wrap CVS initialization in a skip_all check so when CVS initialization
fails, the error report becomes clearer.

Move the Git repo initialization into its own test_expect_success instead
of being in the same CVS check.

Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agohelp: cleanup the contruction of keys_uniq
Amisha Chhajed [Wed, 11 Mar 2026 19:24:53 +0000 (00:54 +0530)] 
help: cleanup the contruction of keys_uniq

construction of keys_uniq depends on sort operation
executed on keys before processing, which does not
gurantee that keys_uniq will be sorted.

refactor the code to shift the sort operation after
the processing to remove dependency on key's sort operation
and strictly maintain the sorted order of keys_uniq.

move strbuf init and release out of loop to reuse same buffer.

dedent sort -u and sed in tests and replace grep with sed, to
avoid piping grep's output to sed.

Suggested-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Amisha Chhajed <amishhhaaaa@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agotest-lib: print escape sequence names
Pablo Sabater [Wed, 11 Mar 2026 03:14:42 +0000 (04:14 +0100)] 
test-lib: print escape sequence names

When printing expected/actual characters in failed checks, use
their names (\a, \b, \n, ...) instead of their octal representation,
making it easier to read.

Add tests to test-example-tap.c
Update t0080-unit-test-output.sh to match the desired output

Teach 'print_one_char()' the equivalent name

Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agosubmodule--helper: replace malloc with xmalloc
Siddharth Shrimali [Tue, 10 Mar 2026 16:44:12 +0000 (22:14 +0530)] 
submodule--helper: replace malloc with xmalloc

The submodule_summary_callback() function currently uses a raw malloc()
which could lead to a NULL pointer dereference.

Standardize this by replacing malloc() with xmalloc() for error handling.
To improve maintainability, use sizeof(*temp) instead of the struct name,
and drop the typecast of void pointer assignment.

Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot3200: replace hardcoded null OID with $ZERO_OID
Siddharth Shrimali [Wed, 11 Mar 2026 17:41:20 +0000 (23:11 +0530)] 
t3200: replace hardcoded null OID with $ZERO_OID

To support the SHA-256 transition, replace the hardcoded 40-zero string
in 'git branch --merged' with '$ZERO_OID'. The current 40-character
string causes the test to fail prematurely in SHA-256 environments
because Git identifies a "malformed object name" (due to the 40 vs 64
character mismatch) before it even validates the object type.

By using '$ZERO_OID', we ensure the hash length is always correct for
the active algorithm. Additionally, use 'test_grep' to verify the
"must point to a commit" error message, ensuring the test validates
the object type logic rather than just string syntax.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agolist-objects-filter-options: avoid strbuf_split_str()
Deveshi Dwivedi [Wed, 11 Mar 2026 17:33:36 +0000 (17:33 +0000)] 
list-objects-filter-options: avoid strbuf_split_str()

parse_combine_filter() splits a combine: filter spec at '+' using
strbuf_split_str(), which yields an array of strbufs with the
delimiter left at the end of each non-final piece.  The code then
mutates each non-final piece to strip the trailing '+' before parsing.

Allocating an array of strbufs is unnecessary.  The function processes
one sub-spec at a time and does not use strbuf editing on the pieces.
The two helpers it calls, has_reserved_character() and
parse_combine_subfilter(), only read the string content of the strbuf
they receive.

Walk the input string directly with strchrnul() to find each '+',
copying each sub-spec into a reusable temporary buffer.  The '+'
delimiter is naturally excluded.  Empty sub-specs (e.g. from a
trailing '+') are silently skipped for consistency.  Change the
helpers to take const char * instead of struct strbuf *.

The test that expected an error on a trailing '+' is removed, since
that behavior was incorrect.

Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoworktree: do not pass strbuf by value
Deveshi Dwivedi [Wed, 11 Mar 2026 17:33:35 +0000 (17:33 +0000)] 
worktree: do not pass strbuf by value

write_worktree_linking_files() takes two struct strbuf parameters by
value, even though it only reads path strings from them.

Passing a strbuf by value is misleading and dangerous. The structure
carries a pointer to its underlying character array; caller and callee
end up sharing that storage.  If the callee ever causes the strbuf to
be reallocated, the caller's copy becomes a dangling pointer, which
results in a double-free when the caller does strbuf_release().

The function only needs the string values, not the strbuf machinery.
Switch it to take const char * and update all callers to pass .buf.

Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoeditorconfig: fix style not applying to subdirs anymore
Patrick Steinhardt [Wed, 11 Mar 2026 07:09:18 +0000 (08:09 +0100)] 
editorconfig: fix style not applying to subdirs anymore

In 046e1117d5 (templates: add .gitattributes entry for sample hooks,
2026-02-13) we have added another pattern to our EditorConfig that sets
the style for our hook templates. As our templates are located in
"templates/hooks/", we explicitly specify that subdirectory as part of
the globbing pattern.

This change causes files in other subdirectories, like for example
"builtin/add.c", to not be configured properly anymore. This seems to
stem from a subtlety in the EditorConfig specification [1]:

  If the glob contains a path separator (a / not inside square
  brackets), then the glob is relative to the directory level of the
  particular .editorconfig file itself. Otherwise the pattern may also
  match at any level below the .editorconfig level.

What's interesting is that the _whole_ expression is considered to be
the glob. So when the expression used is for example "{*.c,foo/*.h}",
then it will be considered a single glob, and because it contains a path
separator we will now anchor "*.c" matches to the same directory as the
".editorconfig" file.

Fix this issue by splitting out the configuration for hook templates
into a separate section. It leads to a tiny bit of duplication, but the
alternative would be something like the following (note the "{,**/}"):

  [{{,**/}*.{c,h,sh,bash,perl,pl,pm,txt,adoc},config.mak.*,{,**/}Makefile,templates/hooks/*.sample}]
  indent_style = tab
  tab_width = 8

This starts to become somewhat hard to read, so the duplication feels
like the better tradeoff.

[1]: https://spec.editorconfig.org/#glob-expressions

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Acked-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot7605: use test_path_is_file instead of test -f
Mansi Singh [Tue, 10 Mar 2026 22:50:22 +0000 (22:50 +0000)] 
t7605: use test_path_is_file instead of test -f

Replace old-style 'test -f' path checks with the modern
test_path_is_file helper in the merge_c1_to_c2_cmds block.

The helper provides clearer failure messages and is the
established convention in Git's test suite.

Signed-off-by: Mansi Singh <mansimaanu8627@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoThe 14th batch
Junio C Hamano [Tue, 10 Mar 2026 20:56:16 +0000 (13:56 -0700)] 
The 14th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoMerge branch 'jh/alias-i18n-fixes'
Junio C Hamano [Tue, 10 Mar 2026 21:23:23 +0000 (14:23 -0700)] 
Merge branch 'jh/alias-i18n-fixes'

Further update to the i18n alias support to avoid regressions.

* jh/alias-i18n-fixes:
  doc: fix list continuation in alias.adoc
  git, help: fix memory leaks in alias listing
  alias: treat empty subsection [alias ""] as plain [alias]
  doc: fix list continuation in alias subsection example

5 weeks agoMerge branch 'pt/fsmonitor-watchman-sample-fix'
Junio C Hamano [Tue, 10 Mar 2026 21:23:22 +0000 (14:23 -0700)] 
Merge branch 'pt/fsmonitor-watchman-sample-fix'

Fix typo-induced breakages in fsmonitor-watchman sample hook.

* pt/fsmonitor-watchman-sample-fix:
  fsmonitor-watchman: fix variable reference and remove redundant code

5 weeks agoMerge branch 'mm/diff-no-index-find-object'
Junio C Hamano [Tue, 10 Mar 2026 21:23:22 +0000 (14:23 -0700)] 
Merge branch 'mm/diff-no-index-find-object'

"git diff --no-index --find-object=<object-name>" outside a
repository of course wouldn't be able to find the object and died
while parsing the command line, which is made to die in a bit more
user-friendly way.

* mm/diff-no-index-find-object:
  diff: fix crash with --find-object outside repository

5 weeks agoMerge branch 'ps/ci-reduce-gitlab-envsize'
Junio C Hamano [Tue, 10 Mar 2026 21:23:21 +0000 (14:23 -0700)] 
Merge branch 'ps/ci-reduce-gitlab-envsize'

CI fix.

* ps/ci-reduce-gitlab-envsize:
  ci: unset GITLAB_FEATURES envvar to not bust xargs(1) limits

5 weeks agoMerge branch 'fp/t3310-test-path-is-helpers'
Junio C Hamano [Tue, 10 Mar 2026 21:23:20 +0000 (14:23 -0700)] 
Merge branch 'fp/t3310-test-path-is-helpers'

Test clean-up.

* fp/t3310-test-path-is-helpers:
  t3310: replace test -f/-d with test_path_is_file/test_path_is_dir

5 weeks agoMerge branch 'ss/test-that-that-typofix'
Junio C Hamano [Tue, 10 Mar 2026 21:23:19 +0000 (14:23 -0700)] 
Merge branch 'ss/test-that-that-typofix'

Typofix in t/.

* ss/test-that-that-typofix:
  t: fix "that that" typo in lib-unicode-nfc-nfd.sh

5 weeks agoMerge branch 'rs/parse-options-duplicated-long-options'
Junio C Hamano [Tue, 10 Mar 2026 21:23:18 +0000 (14:23 -0700)] 
Merge branch 'rs/parse-options-duplicated-long-options'

The parse-options API learned to notice an options[] array with
duplicated long options.

* rs/parse-options-duplicated-long-options:
  parseopt: check for duplicate long names and numerical options
  pack-objects: remove duplicate --stdin-packs definition

5 weeks agoMerge branch 'ar/config-hooks'
Junio C Hamano [Tue, 10 Mar 2026 21:23:18 +0000 (14:23 -0700)] 
Merge branch 'ar/config-hooks'

Allow hook commands to be defined (possibly centrally) in the
configuration files, and run multiple of them for the same hook
event.

* ar/config-hooks:
  hook: add -z option to "git hook list"
  hook: allow out-of-repo 'git hook' invocations
  hook: allow event = "" to overwrite previous values
  hook: allow disabling config hooks
  hook: include hooks from the config
  hook: add "git hook list" command
  hook: run a list of hooks to prepare for multihook support
  hook: add internal state alloc/free callbacks

5 weeks agoMerge branch 'kh/format-patch-noprefix-is-boolean'
Junio C Hamano [Tue, 10 Mar 2026 21:23:17 +0000 (14:23 -0700)] 
Merge branch 'kh/format-patch-noprefix-is-boolean'

The configuration variable format.noprefix did not behave as a
proper boolean variable, which has now been fixed and documented.

* kh/format-patch-noprefix-is-boolean:
  doc: diff-options.adoc: make *.noprefix split translatable
  doc: diff-options.adoc: show format.noprefix for format-patch
  format-patch: make format.noprefix a boolean

5 weeks agoMerge branch 'ps/odb-sources' into ps/object-counting
Junio C Hamano [Tue, 10 Mar 2026 17:13:40 +0000 (10:13 -0700)] 
Merge branch 'ps/odb-sources' into ps/object-counting

* ps/odb-sources:
  odb/source: make `begin_transaction()` function pluggable
  odb/source: make `write_alternate()` function pluggable
  odb/source: make `read_alternates()` function pluggable
  odb/source: make `write_object_stream()` function pluggable
  odb/source: make `write_object()` function pluggable
  odb/source: make `freshen_object()` function pluggable
  odb/source: make `for_each_object()` function pluggable
  odb/source: make `read_object_stream()` function pluggable
  odb/source: make `read_object_info()` function pluggable
  odb/source: make `close()` function pluggable
  odb/source: make `reprepare()` function pluggable
  odb/source: make `free()` function pluggable
  odb/source: introduce source type for robustness
  odb: move reparenting logic into respective subsystems
  odb: embed base source in the "files" backend
  odb: introduce "files" source
  odb: split `struct odb_source` into separate header

6 weeks agodiff: document -U without <n> as using default context
Tian Yuchen [Tue, 10 Mar 2026 09:50:17 +0000 (17:50 +0800)] 
diff: document -U without <n> as using default context

The documentation for '-U<n>' implies that the numeric value '<n>' is
mandatory. However, the command line parser has historically accepted
'-U' without a number.

Strictly requiring a number for '-U' would break existing tests
(e.g., in 't4013') and likely disrupt user scripts relying on this
undocumented behavior.

Hence we retain this fallback behavior for backward compatibility, but
document it as such.

Signed-off-by: Tian Yuchen <cat@malon.dev>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agodir: avoid -Wdiscarded-qualifiers in remove_path()
Collin Funk [Mon, 9 Mar 2026 03:23:06 +0000 (20:23 -0700)] 
dir: avoid -Wdiscarded-qualifiers in remove_path()

When building with glibc-2.43 there is the following warning:

    dir.c:3526:15: warning: assignment discards â€˜const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
     3526 |         slash = strrchr(name, '/');
          |               ^

In this case we use a non-const pointer to get the last slash of the
unwritable file name, and then use it again to write in the strdup'd
file name.

We can avoid this warning and make the code a bit more clear by using a
separate variable to access the original argument and its strdup'd
copy.

Signed-off-by: Collin Funk <collin.funk1@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoSubmittingPatches: spell out "replace fully to pretend to be perfect"
Junio C Hamano [Mon, 9 Mar 2026 22:15:05 +0000 (15:15 -0700)] 
SubmittingPatches: spell out "replace fully to pretend to be perfect"

It unfortunately is a recurring theme that new developers tend to
pile more "fixup" patches on top of the already reviewed patches,
making the topic longer and keeping the history of all wrong turns,
which interests nobody in the larger picture.  Even picking a narrow
search in the list archive for "pretend to be a perfect " substring,
we find these:

    https://lore.kernel.org/git/xmqqk29bsz2o.fsf@gitster.mtv.corp.google.com/
    https://lore.kernel.org/git/xmqqd0ds5ysq.fsf@gitster-ct.c.googlers.com/
    https://lore.kernel.org/git/xmqqr173faez.fsf@gitster.g/

The SubmittingPatches guide does talk about going incremental once a
topic hits the 'next' branch, but it does not say much about how a
new iteration of the topic should be prepared before that happens,
and it does not mention that the developers are encouraged to seize
the opportunity to pretend to be perfect with a full replacement set
of patches.

Add a new paragraph to stress this point in the section that
describes the life-cycle of a patch series.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoThe 13th batch
Junio C Hamano [Mon, 9 Mar 2026 21:35:46 +0000 (14:35 -0700)] 
The 13th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoMerge branch 'jk/repo-structure-cleanup'
Junio C Hamano [Mon, 9 Mar 2026 21:36:56 +0000 (14:36 -0700)] 
Merge branch 'jk/repo-structure-cleanup'

Code clean-up.

* jk/repo-structure-cleanup:
  repo: remove unnecessary variable shadow

6 weeks agoMerge branch 'lp/diff-stat-utf8-display-width-fix'
Junio C Hamano [Mon, 9 Mar 2026 21:36:55 +0000 (14:36 -0700)] 
Merge branch 'lp/diff-stat-utf8-display-width-fix'

"git log --graph --stat" did not count the display width of colored
graph part of its own output correctly, which has been corrected.

* lp/diff-stat-utf8-display-width-fix:
  t4052: test for diffstat width when prefix contains ANSI escape codes
  diff: handle ANSI escape codes in prefix when calculating diffstat width

6 weeks agoMerge branch 'cs/add-skip-submodule-ignore-all'
Junio C Hamano [Mon, 9 Mar 2026 21:36:55 +0000 (14:36 -0700)] 
Merge branch 'cs/add-skip-submodule-ignore-all'

"git add <submodule>" has been taught to honor
submodule.<name>.ignore that is set to "all" (and requires "git add
-f" to override it).

* cs/add-skip-submodule-ignore-all:
  Documentation: update add --force option + ignore=all config
  tests: fix existing tests when add an ignore=all submodule
  tests: t2206-add-submodule-ignored: ignore=all and add --force tests
  read-cache: submodule add need --force given ignore=all configuration
  read-cache: update add_files_to_cache take param ignored_too

6 weeks agoMerge branch 'ps/refs-for-each'
Junio C Hamano [Mon, 9 Mar 2026 21:36:55 +0000 (14:36 -0700)] 
Merge branch 'ps/refs-for-each'

Code refactoring around refs-for-each-* API functions.

* ps/refs-for-each:
  refs: replace `refs_for_each_fullref_in()`
  refs: replace `refs_for_each_namespaced_ref()`
  refs: replace `refs_for_each_glob_ref()`
  refs: replace `refs_for_each_glob_ref_in()`
  refs: replace `refs_for_each_rawref_in()`
  refs: replace `refs_for_each_rawref()`
  refs: replace `refs_for_each_ref_in()`
  refs: improve verification for-each-ref options
  refs: generalize `refs_for_each_fullref_in_prefixes()`
  refs: generalize `refs_for_each_namespaced_ref()`
  refs: speed up `refs_for_each_glob_ref_in()`
  refs: introduce `refs_for_each_ref_ext`
  refs: rename `each_ref_fn`
  refs: rename `do_for_each_ref_flags`
  refs: move `do_for_each_ref_flags` further up
  refs: move `refs_head_ref_namespaced()`
  refs: remove unused `refs_for_each_include_root_ref()`

6 weeks agoMerge branch 'ar/run-command-hook-take-2'
Junio C Hamano [Mon, 9 Mar 2026 21:36:55 +0000 (14:36 -0700)] 
Merge branch 'ar/run-command-hook-take-2'

Use the hook API to replace ad-hoc invocation of hook scripts via
the run_command() API.

* ar/run-command-hook-take-2:
  builtin/receive-pack: avoid spinning no-op sideband async threads
  receive-pack: convert receive hooks to hook API
  receive-pack: convert update hooks to new API
  run-command: poll child input in addition to output
  hook: add jobs option
  reference-transaction: use hook API instead of run-command
  transport: convert pre-push to hook API
  hook: allow separate std[out|err] streams
  hook: convert 'post-rewrite' hook in sequencer.c to hook API
  hook: provide stdin via callback
  run-command: add stdin callback for parallelization
  run-command: add helper for pp child states
  t1800: add hook output stream tests

6 weeks agoMerge branch 'ar/config-hooks' into ar/config-hook-cleanups
Junio C Hamano [Mon, 9 Mar 2026 20:07:50 +0000 (13:07 -0700)] 
Merge branch 'ar/config-hooks' into ar/config-hook-cleanups

* ar/config-hooks: (21 commits)
  builtin/receive-pack: avoid spinning no-op sideband async threads
  hook: add -z option to "git hook list"
  hook: allow out-of-repo 'git hook' invocations
  hook: allow event = "" to overwrite previous values
  hook: allow disabling config hooks
  hook: include hooks from the config
  hook: add "git hook list" command
  hook: run a list of hooks to prepare for multihook support
  hook: add internal state alloc/free callbacks
  receive-pack: convert receive hooks to hook API
  receive-pack: convert update hooks to new API
  run-command: poll child input in addition to output
  hook: add jobs option
  reference-transaction: use hook API instead of run-command
  transport: convert pre-push to hook API
  hook: allow separate std[out|err] streams
  hook: convert 'post-rewrite' hook in sequencer.c to hook API
  hook: provide stdin via callback
  run-command: add stdin callback for parallelization
  run-command: add helper for pp child states
  ...

6 weeks ago.mailmap: update email address for Tian Yuchen
Tian Yuchen [Sun, 8 Mar 2026 04:33:44 +0000 (12:33 +0800)] 
.mailmap: update email address for Tian Yuchen

Map my old Gmail address to my new custom address in .mailmap.

Signed-off-by: Tian Yuchen <a3205153416@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agopatch-ids: document intentional const-casting in patch_id_neq()
Tian Yuchen [Mon, 9 Mar 2026 06:51:40 +0000 (14:51 +0800)] 
patch-ids: document intentional const-casting in patch_id_neq()

The hashmap API requires the comparison function to take const pointers.
However, patch_id_neq() uses lazy evaluation to compute patch IDs on
demand. As established in b3dfeebb (rebase: avoid computing unnecessary
patch IDs, 2016-07-29), this avoids unnecessary work since not all
objects in the hashmap will eventually be compared.

Remove the ten-year-old "NEEDSWORK" comment and formally document
this intentional design trade-off.

Signed-off-by: Tian Yuchen <cat@malon.dev>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agohistory: initialize rev_info in cmd_history_reword()
René Scharfe [Sun, 8 Mar 2026 09:57:02 +0000 (10:57 +0100)] 
history: initialize rev_info in cmd_history_reword()

git history reword expects a single valid revision argument and errors
out if it doesn't get it.  In that case the struct rev_info passed to
release_revisions() for cleanup is still uninitialized, which can result
in attempts to free(3) random pointers.  Avoid that by initializing the
structure.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agobloom: remove a misleading const qualifier
Collin Funk [Mon, 9 Mar 2026 02:55:11 +0000 (19:55 -0700)] 
bloom: remove a misleading const qualifier

When building with glibc-2.43 there is the following warning:

    bloom.c: In function â€˜get_or_compute_bloom_filter’:
    bloom.c:515:52: warning: initialization discards â€˜const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
      515 |                                 char *last_slash = strrchr(path, '/');
          |                                                    ^~~~~~~

In this case, we always write through "path" through the "last_slash"
pointer. Therefore, the const qualifier on "path" is misleading and we
can just remove it.

Signed-off-by: Collin Funk <collin.funk1@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot3310: avoid hiding failures from rev-parse in command substitutions
Francesco Paparatto [Sat, 7 Mar 2026 10:36:31 +0000 (11:36 +0100)] 
t3310: avoid hiding failures from rev-parse in command substitutions

Running `git` commands inside command substitutions like

    test "$(git rev-parse A)" = "$(git rev-parse B)"

can hide failures from the `git` invocations and provide little
diagnostic information when `test` fails.

Use `test_cmp` when comparing against a stored expected value so
mismatches show both expected and actual output. Use `test_cmp_rev`
when comparing two revisions. These helpers produce clearer failure
output, making it easier to understand what went wrong.

Suggested-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Francesco Paparatto <francescopaparatto@gmail.com>
Reviewed-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agodoc: make it easier to find custom command information
Omri Sarig [Sat, 7 Mar 2026 17:08:01 +0000 (17:08 +0000)] 
doc: make it easier to find custom command information

Git supports creating additional commands through aliases, and through
placement of executables with a "git-" prefix in the PATH.

This information was not easy enough to find - users will look for this
information around the command description, but the documentation
exists in other locations.

Update the "GIT COMMANDS" section to reference the relevant sections,
making it easier for to find this information.

Signed-off-by: Omri Sarig <omri.sarig13@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agomeson: turn on NO_MMAP when building with LSan
Jeff King [Fri, 6 Mar 2026 16:25:13 +0000 (11:25 -0500)] 
meson: turn on NO_MMAP when building with LSan

The previous commit taught the Makefile to turn on NO_MMAP in this
instance. We should do the same with meson for consistency. We already
do this for ASan builds, so we can just tweak one conditional.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoMakefile: turn on NO_MMAP when building with LSan
Jeff King [Thu, 5 Mar 2026 23:13:05 +0000 (18:13 -0500)] 
Makefile: turn on NO_MMAP when building with LSan

The past few commits fixed some cases where we leak memory allocated by
mmap(). Building with SANITIZE=leak doesn't detect these because it
covers only heap buffers allocated by malloc().

But if we build with NO_MMAP, our compat mmap() implementation will
allocate a heap buffer and pread() into it. And thus Lsan will detect
these leaks for free.

Using NO_MMAP is less performant, of course, since we have to use extra
memory and read in the whole file, rather than faulting in pages from
disk. But LSan builds are already slow, and this doesn't make them
measurably worse. Getting extra coverage for our leak-checking is worth
it.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoobject-file: fix mmap() leak in odb_source_loose_read_object_stream()
Jeff King [Sat, 7 Mar 2026 02:24:59 +0000 (21:24 -0500)] 
object-file: fix mmap() leak in odb_source_loose_read_object_stream()

We mmap() a loose object file, storing the result in the local variable
"mapped", which is eventually assigned into our stream struct as
"st.mapped". If we hit an error, we jump to an error label which does:

  munmap(st.mapped, st.mapsize);

to clean up. But this is wrong; we don't assign st.mapped until the end
of the function, after all of the "goto error" jumps. So this munmap()
is never cleaning up anything (st.mapped is always NULL, because we
initialize the struct with calloc).

Instead, we should feed the local variable to munmap().

This leak is due to 595296e124 (streaming: allocate stream inside the
backend-specific logic, 2025-11-23), which introduced the local
variable. Before that, we assigned the mmap result directly into
st.mapped. It was probably switched there so that we do not have to
allocate/free the struct when the map operation fails (e.g., because we
don't have the loose object). Before that commit, the struct was passed
in from the caller, so there was no allocation at all.

You can see the leak in the test suite by building with:

  make SANITIZE=leak NO_MMAP=1 CC=clang

and running t1060. We need NO_MMAP so that the mmap() is backed by an
actual malloc(), which allows LSan to detect it. And the leak seems not
to be detected when compiling with gcc, probably due to some internal
compiler decisions about how the stack memory is written.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agodocs: add usage for the cover-letter fmt feature
Mirko Faina [Fri, 6 Mar 2026 23:34:44 +0000 (00:34 +0100)] 
docs: add usage for the cover-letter fmt feature

Document the new "--cover-letter-format" option in format-patch and its
related configuration variable "format.commitListFormat".

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoformat-patch: add commitListFormat config
Mirko Faina [Fri, 6 Mar 2026 23:34:43 +0000 (00:34 +0100)] 
format-patch: add commitListFormat config

Using "--cover-letter" we can tell format-patch to generate a cover
letter, in this cover letter there's a list of commits included in the
patch series and the format is specified by the "--cover-letter-format"
option. Would be useful if this format could be configured from the
config file instead of always needing to pass it from the command line.

Teach format-patch how to read the format spec for the cover letter from
the config files. The variable it should look for is called
format.commitListFormat.

Possible values:
  - commitListFormat is set but no string is passed: it will default to
    "[%(count)/%(total)] %s"

  - if a string is passed: will use it as a format spec. Note that this
    is either "shortlog" or a format spec prefixed by "log:"
    e.g."log:%s (%an)"

  - if commitListFormat is not set: it will default to the shortlog
    format.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoformat-patch: add ability to use alt cover format
Mirko Faina [Fri, 6 Mar 2026 23:34:42 +0000 (00:34 +0100)] 
format-patch: add ability to use alt cover format

Often when sending patch series there's a need to clarify to the
reviewer what's the purpose of said series, since it might be difficult
to understand it from reading the commits messages one by one.

"git format-patch" provides the useful "--cover-letter" flag to declare
if we want it to generate a template for us to use. By default it will
generate a "git shortlog" of the changes, which developers find less
useful than they'd like, mainly because the shortlog groups commits by
author, and gives no obvious chronological order.

Give format-patch the ability to specify an alternative format spec
through the "--cover-letter-format" option. This option either takes
"shortlog", which is the current format, or a format spec prefixed with
"log:".

Example:
    git format-patch --cover-letter \
        --cover-letter-format="log:[%(count)/%(total)] %s (%an)" HEAD~3

    [1/3] this is a commit summary (Mirko Faina)
    [2/3] this is another commit summary (Mirko Faina)
    ...

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoformat-patch: move cover letter summary generation
Mirko Faina [Fri, 6 Mar 2026 23:34:41 +0000 (00:34 +0100)] 
format-patch: move cover letter summary generation

As of now format-patch allows generation of a template cover letter for
patch series through "--cover-letter".

Move shortlog summary code generation to its own function. This is done
in preparation to other patches where we enable the user to format the
commit list using thier own format string.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agopretty.c: add %(count) and %(total) placeholders
Mirko Faina [Fri, 6 Mar 2026 23:34:40 +0000 (00:34 +0100)] 
pretty.c: add %(count) and %(total) placeholders

In many commands we can customize the output through the "--format" or
the "--pretty" options. This patch adds two new placeholders used mainly
when there's a range of commits that we want to show.

Currently these two placeholders are not usable as they're coupled with
the rev_info->nr and rev_info->total fields, fields that are used only
by the format-patch numbered email subjects.

Teach repo_format_commit_message() the %(count) and %(total)
placeholders.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoDocumentation: extend guidance for submitting patches
Justin Tobler [Thu, 5 Mar 2026 19:38:36 +0000 (13:38 -0600)] 
Documentation: extend guidance for submitting patches

Before submitting patches on the mailing list, it is often a good idea
to check for previous related discussions or if similar work is already
in progress. This enables better coordination amongst contributors and
could avoid duplicating work.

Additionally, it is often recommended to give reviewers some time to
reply to a patch series before sending new versions. This helps collect
broader feedback and reduces unnecessary churn from rapid rerolls.

Document this guidance in "Documentation/SubmittingPatches" accordingly.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agopack-revindex: avoid double-loading .rev files
Jeff King [Thu, 5 Mar 2026 23:12:29 +0000 (18:12 -0500)] 
pack-revindex: avoid double-loading .rev files

The usual entry point for loading the pack revindex is the
load_pack_revindex() function. It returns immediately if the packed_git
has a non-NULL revindex or revindex data field (representing an
in-memory or mmap'd .rev file, respectively), since the data is already
loaded.

But in 5a6072f631 (fsck: validate .rev file header, 2023-04-17) the fsck
code path switched to calling load_pack_revindex_from_disk() directly,
since it wants to check the on-disk data (if there is any). But that
function does _not_ check to see if the data has already been loaded; it
just maps the file, overwriting the revindex_map pointer (and pointing
revindex_data inside that map). And in that case we've leaked the mmap()
pointed to by revindex_map (if it was non-NULL).

This usually doesn't happen, since fsck wouldn't need to load the
revindex for any reason before we get to these checks. But there are
some cases where it does. For example, is_promisor_object() runs
odb_for_each_object() with the PACK_ORDER flag, which uses the revindex.

This happens a few times in our test suite, but SANITIZE=leak doesn't
detect it because we are leaking an mmap(), not a heap-allocated buffer
from malloc(). However, if you build with NO_MMAP, then our compat mmap
will read into a heap buffer instead, and LSan will complain. This
causes failures in t5601, t0410, t5702, and t5616.

We can fix it by checking for existing revindex_data when loading from
disk. This is redundant when we're called from load_pack_revindex(), but
it's a cheap check. The alternative is to teach check_pack_rev_indexes()
in fsck to skip the load, but that seems messier; it doesn't otherwise
know about internals like revindex_map and revindex_data.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agocheck_connected(): fix leak of pack-index mmap
Jeff King [Thu, 5 Mar 2026 23:09:56 +0000 (18:09 -0500)] 
check_connected(): fix leak of pack-index mmap

Since c6807a40dc (clone: open a shortcut for connectivity check,
2013-05-26), we may open a one-off packed_git struct to check what's in
the pack we just received. At the end of the function we throw away the
struct (rather than linking it into the repository struct as usual).

We used to leak the struct until dd4143e7bf (connected.c: free the
"struct packed_git", 2022-11-08), which calls free(). But that's not
sufficient; inside the struct we'll have mmap'd the pack idx data from
disk, which needs an munmap() call.

Building with SANITIZE=leak doesn't detect this, because we are leaking
our own mmap(), and it only finds heap allocations from malloc(). But if
we use our compat mmap implementation like this:

  make NO_MMAP=MapsBecomeMallocs SANITIZE=leak

then LSan will notice the leak, because now it's a regular heap buffer
allocated by malloc().

We can fix it by calling close_pack(), which will free any associated
memory. Note that we need to check for NULL ourselves; unlike free(), it
is not safe to pass a NULL pointer to close_pack().

Signed-off-by: Jeff King <peff@peff.net>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agocheck_connected(): delay opening new_pack
Jeff King [Thu, 5 Mar 2026 23:08:54 +0000 (18:08 -0500)] 
check_connected(): delay opening new_pack

In check_connected(), if the transport tells us we got a single packfile
that has already been verified as self-contained and connected, then we
can skip checking connectivity for any tips that are mentioned in that
pack. This goes back to c6807a40dc (clone: open a shortcut for
connectivity check, 2013-05-26).

We don't need to open that pack until we are about to start sending oids
to our child rev-list process, since that's when we check whether they
are in the self-contained pack. Let's push the opening of that pack
further down in the function. That saves us from having to clean it up
when we leave the function early (and by the time have opened the
rev-list process, we never leave the function early, since we have to
clean up the child process).

Signed-off-by: Jeff King <peff@peff.net>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agorebase: support --trailer
Li Chen [Fri, 6 Mar 2026 14:53:32 +0000 (14:53 +0000)] 
rebase: support --trailer

Add a new --trailer=<trailer> option to git rebase to append trailer
lines to each rewritten commit message (merge backend only).

Because the apply backend does not provide a commit-message filter,
reject --trailer when --apply is in effect and require the merge backend
instead.

This option implies --force-rebase so that fast-forwarded commits are
also rewritten. Validate trailer arguments early to avoid starting an
interactive rebase with invalid input.

Add integration tests covering error paths and trailer insertion across
non-interactive and interactive rebases.

Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agocommit, tag: parse --trailer with OPT_STRVEC
Li Chen [Fri, 6 Mar 2026 14:53:31 +0000 (14:53 +0000)] 
commit, tag: parse --trailer with OPT_STRVEC

Now that amend_file_with_trailers() expects raw trailer lines, do not
store argv-style "--trailer=<trailer>" strings in git commit and git
tag.

Parse --trailer using OPT_STRVEC so trailer_args contains only the
trailer value, and drop the temporary prefix stripping in
amend_file_with_trailers().

Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agotrailer: append trailers without fork/exec
Li Chen [Fri, 6 Mar 2026 14:53:30 +0000 (14:53 +0000)] 
trailer: append trailers without fork/exec

Introduce amend_strbuf_with_trailers() to apply trailer additions to a
message buffer via process_trailers(), avoiding the need to run git
interpret-trailers as a child process.

Update amend_file_with_trailers() to use the in-process helper and
rewrite the target file via tempfile+rename, preserving the previous
in-place semantics. As the trailers are no longer added in a separate
process and trailer_config_init() die()s on missing config values it
is called early on in cmd_commit() and cmd_tag() so that they die()
early before writing the message file. The trailer arguments are now
also sanity checked.

Keep existing callers unchanged by continuing to accept argv-style
--trailer=<trailer> entries and stripping the prefix before feeding the
in-process implementation.

Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agotrailer: libify a couple of functions
Li Chen [Fri, 6 Mar 2026 14:53:29 +0000 (14:53 +0000)] 
trailer: libify a couple of functions

Move create_in_place_tempfile() and process_trailers() from
builtin/interpret-trailers.c into trailer.c and expose it via trailer.h.

This reverts most of ae0ec2e0e0b (trailer: move interpret_trailers()
to interpret-trailers.c, 2024-03-01) and lets other call sites reuse
the same trailer rewriting logic.

Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agointerpret-trailers: refactor create_in_place_tempfile()
Phillip Wood [Fri, 6 Mar 2026 14:53:28 +0000 (14:53 +0000)] 
interpret-trailers: refactor create_in_place_tempfile()

Refactor create_in_place_tempfile() in preparation for moving it
to tralier.c. Change the return type to return a `struct tempfile*`
instead of a `FILE*` so that we can remove the file scope tempfile
variable. Since 076aa2cbda5 (tempfile: auto-allocate tempfiles on
heap, 2017-09-05) it has not been necessary to make tempfile varibales
static so this is safe. Also use error() and return NULL in place of
die() so the caller can exit gracefully and use find_last_dir_sep()
rather than strchr() to find the parent directory.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agointerpret-trailers: factor trailer rewriting
Li Chen [Fri, 6 Mar 2026 14:53:27 +0000 (14:53 +0000)] 
interpret-trailers: factor trailer rewriting

Extract the trailer rewriting logic into a helper that appends to an
output strbuf.

Update interpret_trailers() to handle file I/O only: read input once,
call the helper, and write the buffered result.

This separation makes it easier to move the helper into trailer.c in the
next commit.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `begin_transaction()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:57 +0000 (15:19 +0100)] 
odb/source: make `begin_transaction()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `write_alternate()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:56 +0000 (15:19 +0100)] 
odb/source: make `write_alternate()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `read_alternates()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:55 +0000 (15:19 +0100)] 
odb/source: make `read_alternates()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `write_object_stream()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:54 +0000 (15:19 +0100)] 
odb/source: make `write_object_stream()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `write_object()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:53 +0000 (15:19 +0100)] 
odb/source: make `write_object()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `freshen_object()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:52 +0000 (15:19 +0100)] 
odb/source: make `freshen_object()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `for_each_object()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:51 +0000 (15:19 +0100)] 
odb/source: make `for_each_object()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `read_object_stream()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:50 +0000 (15:19 +0100)] 
odb/source: make `read_object_stream()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoodb/source: make `read_object_info()` function pluggable
Patrick Steinhardt [Thu, 5 Mar 2026 14:19:49 +0000 (15:19 +0100)] 
odb/source: make `read_object_info()` function pluggable

Introduce a new callback function in `struct odb_source` to make the
function pluggable.

Note that this function is a bit less straight-forward to convert
compared to the other functions. The reason here is that the logic to
read an object is:

  1. We try to read the object. If it exists we return it.

  2. If the object does not exist we reprepare the object database
     source.

  3. We then try reading the object info a second time in case the
     reprepare caused it to appear.

The second read is only supposed to happen for the packfile store
though, as reading loose objects is not impacted by repreparing the
object database.

Ideally, we'd just move this whole logic into the ODB source. But that's
not easily possible because we try to avoid the reprepare unless really
required, which is after we have found out that no other ODB source
contains the object, either. So the logic spans across multiple ODB
sources, and consequently we cannot move it into an individual source.

Instead, introduce a new flag `OBJECT_INFO_SECOND_READ` that tells the
backend that we already tried to look up the object once, and that this
time around the ODB source should try to find any new objects that may
have surfaced due to an on-disk change.

With this flag, the "files" backend can trivially skip trying to re-read
the object as a loose object. Furthermore, as we know that we only try
the second read via the packfile store, we can skip repreparing loose
objects and only reprepare the packfile store.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>