]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
3 weeks agohttp: add support for HTTP 429 rate limit retries
Vaidas Pilkauskas [Tue, 17 Mar 2026 13:00:35 +0000 (13:00 +0000)] 
http: add support for HTTP 429 rate limit retries

Add retry logic for HTTP 429 (Too Many Requests) responses to handle
server-side rate limiting gracefully. When Git's HTTP client receives
a 429 response, it can now automatically retry the request after an
appropriate delay, respecting the server's rate limits.

The implementation supports the RFC-compliant Retry-After header in
both delay-seconds (integer) and HTTP-date (RFC 2822) formats. If a
past date is provided, Git retries immediately without waiting.

Retry behavior is controlled by three new configuration options
(http.maxRetries, http.retryAfter, and http.maxRetryTime) which are
documented in git-config(1).

The retry logic implements a fail-fast approach: if any delay
(whether from server header or configuration) exceeds maxRetryTime,
Git fails immediately with a clear error message rather than capping
the delay. This provides better visibility into rate limiting issues.

The implementation includes extensive test coverage for basic retry
behavior, Retry-After header formats (integer and HTTP-date),
configuration combinations, maxRetryTime limits, invalid header
handling, environment variable overrides, and edge cases.

Signed-off-by: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agostrbuf_attach: fix call sites to pass correct alloc
Vaidas Pilkauskas [Tue, 17 Mar 2026 13:00:34 +0000 (13:00 +0000)] 
strbuf_attach: fix call sites to pass correct alloc

strbuf_attach(sb, buf, len, alloc) requires alloc > len (the buffer
must have at least len+1 bytes to hold the NUL). Several call sites
passed alloc == len, relying on strbuf_grow(sb, 0) inside strbuf_attach
to reallocate. Fix these in mailinfo, am, refs/files-backend,
fast-import, and trailer by passing len+1 when the buffer is a
NUL-terminated string (or from strbuf_detach).

Signed-off-by: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agostrbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()
Vaidas Pilkauskas [Tue, 17 Mar 2026 13:00:33 +0000 (13:00 +0000)] 
strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()

reencode_string_len() allocates len+1 bytes (including the NUL) and
returns the string length in len. strbuf_reencode() was calling
strbuf_attach(sb, out, len, len), so alloc was one byte too small.

strbuf_attach() then calls strbuf_grow(sb, 0). With alloc < len+1,
ALLOC_GROW always reallocates, so we reallocated immediately after
attach even when the strbuf was not extended further. Pass len+1 as
the alloc argument so the existing buffer is reused and the
reallocation is avoided.

Signed-off-by: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agot2203: avoid suppressing git status exit code
Jialong Wang [Tue, 17 Mar 2026 01:15:44 +0000 (21:15 -0400)] 
t2203: avoid suppressing git status exit code

When git status is piped into grep, the exit status of the Git
command is hidden by the pipeline. Capture the status output in a
temporary file first, and then filter it as needed, so that any
failure from git status is still noticed by the test suite.

Signed-off-by: Jialong Wang <jerrywang183@yahoo.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agodoc: note that -L supports patch formatting and pickaxe options
Michael Montalbo [Tue, 17 Mar 2026 02:21:35 +0000 (02:21 +0000)] 
doc: note that -L supports patch formatting and pickaxe options

Now that -L output flows through the standard diff pipeline,
document that patch formatting options like --word-diff,
--color-moved, --no-prefix, whitespace handling (-w, -b),
and pickaxe options (-S, -G) are supported.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agot4211: add tests for -L with standard diff options
Michael Montalbo [Tue, 17 Mar 2026 02:21:34 +0000 (02:21 +0000)] 
t4211: add tests for -L with standard diff options

Now that -L output flows through the standard diff pipeline, verify
that previously-ignored diff options work: formatting (--word-diff,
--word-diff-regex, --no-prefix, --src/dst-prefix, --full-index,
--abbrev), whitespace handling (-w, -b), output indicators
(--output-indicator-new/old/context), direction reversal (-R),
--color-moved, and pickaxe options (-S, -G).

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoline-log: route -L output through the standard diff pipeline
Michael Montalbo [Tue, 17 Mar 2026 02:21:33 +0000 (02:21 +0000)] 
line-log: route -L output through the standard diff pipeline

`git log -L` has always bypassed the standard diff pipeline.
`dump_diff_hacky()` in line-log.c hand-rolls its own diff headers and
hunk output, which means most diff formatting options are silently
ignored.  A NEEDSWORK comment has acknowledged this since the feature
was introduced:

    /*
     * NEEDSWORK: manually building a diff here is not the Right
     * Thing(tm).  log -L should be built into the diff pipeline.
     */

Remove `dump_diff_hacky()` and its helpers and route -L output through
`builtin_diff()` / `fn_out_consume()`, the same path used by `git diff`
and `git log -p`.  The mechanism is a pair of callback wrappers that sit
between `xdi_diff_outf()` and `fn_out_consume()`, filtering xdiff's
output to only the tracked line ranges.  To ensure xdiff emits all lines
within each range as context, the context length is inflated to span the
largest range.

Wire up the `-L` implies `--patch` default in revision setup rather
than forcing it at output time, so `line_log_print()` is just
`diffcore_std()` + `diff_flush()` with no format save/restore.
Rename detection is a no-op since pairs are already resolved during
the history walk in `queue_diffs()`, but running `diffcore_std()`
means `-S`/`-G` (pickaxe), `--orderfile`, and `--diff-filter` now
work with `-L`, and `diff_resolve_rename_copy()` sets pair statuses
correctly without manual assignment.

Switch `diff_filepair_dup()` from `xmalloc` to `xcalloc` so that new
fields (including `line_ranges`) are zero-initialized by default.

As a result, diff formatting options that were previously silently
ignored (e.g. --word-diff, --no-prefix, -w, --color-moved) now work
with -L, and output gains `index` lines, `new file mode` headers, and
funcname context in `@@` headers.  This is a user-visible output change:
tools that parse -L output may need to handle the additional header
lines.

The context-length inflation means xdiff may process more output than
needed for very wide line ranges, but benchmarks on files up to 7800
lines show no measurable regression.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoline-log: fix crash when combined with pickaxe options
Michael Montalbo [Tue, 17 Mar 2026 02:21:32 +0000 (02:21 +0000)] 
line-log: fix crash when combined with pickaxe options

queue_diffs() passes the caller's diff_options, which may carry
user-specified pickaxe state, to diff_tree_oid() and diffcore_std()
when detecting renames for line-level history tracking.  When pickaxe
options are present on the command line (-G and -S to filter by text
pattern, --find-object to filter by object identity), diffcore_std()
also runs diffcore_pickaxe(), which may discard diff pairs that are
relevant for rename detection.  Losing those pairs breaks rename
following.

Before a2bb801f6a (line-log: avoid unnecessary full tree diffs,
2019-08-21), this silently truncated history at rename boundaries.
That commit moved filter_diffs_for_paths() inside the rename-
detection block, so it only runs when diff_might_be_rename() returns
true.  When pickaxe discards a rename pair, the rename goes
undetected, and a deletion pair at a subsequent commit passes
through uncleaned, reaching process_diff_filepair() with an invalid
filespec and triggering an assertion failure.

Fix this by building a private diff_options for the rename-detection
path inside queue_diffs(), following the same pattern used by blame's
find_rename().  This isolates the rename machinery from unrelated
user-specified options.

Reported-by: Matthew Hughes <matthewhughes934@gmail.com>
Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agorefs: add 'preparing' phase to the reference-transaction hook
Eric Ju [Tue, 17 Mar 2026 02:36:24 +0000 (22:36 -0400)] 
refs: add 'preparing' phase to the reference-transaction hook

The "reference-transaction" hook is invoked multiple times during a ref
transaction. Each invocation corresponds to a different phase:

- The "prepared" phase indicates that references have been locked.
- The "committed" phase indicates that all updates have been written to disk.
- The "aborted" phase indicates that the transaction has been aborted and that
  all changes have been rolled back.

This hook can be used to learn about the updates that Git wants to perform.
For example, forges use it to coordinate reference updates across multiple
nodes.

However, the phases are insufficient for some specific use cases. The earliest
observable phase in the "reference-transaction" hook is "prepared", at which
point Git has already taken exclusive locks on every affected reference. This
makes it suitable for last-chance validation, but not for serialization. So by
the time a hook sees the "prepared" phase, it has no way to defer locking, and
thus it cannot rearrange multiple concurrent ref transactions relative to one
another.

Introduce a new "preparing" phase that runs before the "prepared" phase, that
is before Git acquires any reference lock on disk. This gives callers a
well-defined window to perform validation, enable higher-level ordering of
concurrent transactions, or reject the transaction entirely, all without
interfering with the locking state.

This change is strictly speaking not backwards compatible. Existing hook
scripts that do not know how to handle unknown phases may treat 'preparing'
as an error and return non-zero. But the hook is considered to expose
internal implementation details of how Git works, and as such we have
been a bit more lenient with changing its exact semantics, like for example
in a8ae923f85 (refs: support symrefs in 'reference-transaction' hook, 2024-05-07).

An alternative would be to introduce a "reference-transaction-v2" hook that
knows about the new phase. This feels like a rather heavy-weight option though,
and was thus discarded.

Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Justin Tobler <jltobler@gmail.com>
Helped-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Eric Ju <eric.peijian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agointerpret-trailers: use placeholder instead of *
Kristoffer Haugsbakk [Mon, 16 Mar 2026 21:48:27 +0000 (22:48 +0100)] 
interpret-trailers: use placeholder instead of *

Use `<key-alias>` instead of `*` in order to be consistent with
the documentation.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agodoc: config: convert trailers section to synopsis style
Kristoffer Haugsbakk [Mon, 16 Mar 2026 21:48:26 +0000 (22:48 +0100)] 
doc: config: convert trailers section to synopsis style

Convert this part of the configuration documentation to synopsis style
so that all of git-interpret-trailers(1) is consistent.

See the commit message from two commits ago.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agodoc: interpret-trailers: normalize and fill out options
Kristoffer Haugsbakk [Mon, 16 Mar 2026 21:48:25 +0000 (22:48 +0100)] 
doc: interpret-trailers: normalize and fill out options

Some negated options are missing according to
`git interpret-trailers -h`.

Also normalize to the “stuck form” (see gitcli(7)) like what was done
in 806337c7 (doc: notes: use stuck form throughout, 2025-05-27).[1]

Also normalize the order of the regular and negated options according to
the current convention.[2]

Also note that `--no-trailer` will reset the list.

† 1: See also https://lore.kernel.org/git/6f7d027e-088a-4d66-92af-b8d1c32d730c@app.fastmail.com/
† 2: https://lore.kernel.org/git/xmqqcyct1mtq.fsf@gitster.g/

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agodoc: interpret-trailers: convert to synopsis style
Kristoffer Haugsbakk [Mon, 16 Mar 2026 21:48:24 +0000 (22:48 +0100)] 
doc: interpret-trailers: convert to synopsis style

See e.g. 0ae23ab5 (doc: convert git worktree to synopsis style,
2025-10-05) for the markup rules for this style.

There aren’t many subtleties to the transformation of this doc since it
doesn’t use any advanced constructs. The only thing is that "`:`{nbsp}" is
used instead of `': '` to refer to effective inline-verbatim with
a space (␠).[1] I also use (_) for emphasis although (') gives the
same result.

Also prefer linking to Git commands instead of saying e.g. `git
format-patch`. But for this command we can type out git-interpret-
trailers(1) to avoid a self-reference.

Also replace camel case `<keyAlias>` with kebab case `<key-alias>`.
And while doing that make sure to replace `trailer.*` with
`trailer.<key-alias>`.

† 1: Similar to "`tag:`{nbsp}" in `Documentation/pretty-formats.adoc`

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agotransport: plug leaks in transport_color_config()
Jeff King [Sat, 14 Mar 2026 16:08:14 +0000 (12:08 -0400)] 
transport: plug leaks in transport_color_config()

We retrieve config values with repo_config_get_string(), which will
allocate a new copy of the string for us. But we don't hold on to those
strings, since they are just fed to git_config_colorbool() and
color_parse(). But nor do we free them, which means they leak.

We can fix this by using the "_tmp" form of repo_config_get_string(),
which just hands us a pointer directly to the internal storage. This is
OK for our purposes, since we don't need it to last for longer than our
parsing calls.

Two interesting side notes here:

  1. Many types already have a repo_config_get_X() variant that handles
     this for us (e.g., repo_config_get_bool()). But neither colorbools
     nor colors themselves have such helpers. We might think about
     adding them, but converting all callers is a larger task, and out
     of scope for this fix.

  2. As far as I can tell, this leak has been there since 960786e761
     (push: colorize errors, 2018-04-21), but wasn't detected by LSan in
     our test suite. It started triggering when we applied dd3693eb08
     (transport-helper, connect: use clean_on_exit to reap children on
     abnormal exit, 2026-03-12) which is mostly unrelated.

     Even weirder, it seems to trigger only with clang (and not gcc),
     and only with GIT_TEST_DEFAULT_REF_FORMAT=reftable. So I think this
     is another odd case where the pointers happened to be hanging
     around in stack memory, but changing the pattern of function calls
     in nearby code was enough for them to be incidentally overwritten.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agot4200: convert test -[df] checks to test_path_* helpers
PRASHANT S BISHT [Mon, 16 Mar 2026 17:24:57 +0000 (22:54 +0530)] 
t4200: convert test -[df] checks to test_path_* helpers

Replace old-style path existence checks in t4200-rerere.sh with
the appropriate test_path_* helper functions. These helpers provide
clearer diagnostic messages on failure than the raw shell test
builtin.

Signed-off-by: Prashant S Bisht <prashantjee2025@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoapply.c: fix -p argument parsing
Mirko Faina [Mon, 16 Mar 2026 00:51:16 +0000 (01:51 +0100)] 
apply.c: fix -p argument parsing

"git apply" has an option -p that takes an integer as its argument.
Unfortunately the function apply_option_parse_p() in charge of parsing
this argument uses atoi() to convert from string to integer, which
allows a non-digit after the number (e.g. "1q") to be silently ignored.
As a consequence, an argument that does not begin with a digit silently
becomes a zero. Despite this command working fine when a non-positive
argument is passed, it might be useful for the end user to know that
their input contains non-digits that might've been unintended.

Replace atoi() with strtol_i() to catch malformed inputs.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agot0008: improve test cleanup to fix failing test
Mirko Faina [Mon, 16 Mar 2026 01:15:42 +0000 (02:15 +0100)] 
t0008: improve test cleanup to fix failing test

The "large exclude file ignored in tree" test fails. This is due to an
additional warning message that is generated in the test. "warning:
unable to access 'subdir/.gitignore': Too many levels of symbolic
links", the extra warning that is not supposed to be there, happens
because of some leftover files left by previous tests.

To fix this we improve cleanup on "symlinks not respected in-tree", and
because the tests in t0008 in general have poor cleanup, at the start of
"large exclude file ignored in tree" we search for any leftover
.gitignore and remove them before starting the test.

Improve post-test cleanup and add pre-test cleanup to make sure that we
have a workable environment for the test.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoMerge branch 'mf/format-patch-cover-letter-format' into mf/format-patch-commit-list...
Junio C Hamano [Mon, 16 Mar 2026 19:42:54 +0000 (12:42 -0700)] 
Merge branch 'mf/format-patch-cover-letter-format' into mf/format-patch-commit-list-format

* mf/format-patch-cover-letter-format:
  docs: add usage for the cover-letter fmt feature
  format-patch: add commitListFormat config
  format-patch: add ability to use alt cover format
  format-patch: move cover letter summary generation
  pretty.c: add %(count) and %(total) placeholders

3 weeks agoThe 17th batch
Junio C Hamano [Mon, 16 Mar 2026 17:48:02 +0000 (10:48 -0700)] 
The 17th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoMerge branch 'ty/patch-ids-document-lazy-eval'
Junio C Hamano [Mon, 16 Mar 2026 17:48:15 +0000 (10:48 -0700)] 
Merge branch 'ty/patch-ids-document-lazy-eval'

In-code comment update to record a design decision to allow lazy
computation of patch IDs.

* ty/patch-ids-document-lazy-eval:
  patch-ids: document intentional const-casting in patch_id_neq()

3 weeks agoMerge branch 'rs/history-ergonomics-updates-fix'
Junio C Hamano [Mon, 16 Mar 2026 17:48:15 +0000 (10:48 -0700)] 
Merge branch 'rs/history-ergonomics-updates-fix'

Fix use of uninitialized variable.

* rs/history-ergonomics-updates-fix:
  history: initialize rev_info in cmd_history_reword()

3 weeks agoMerge branch 'jk/unleak-mmap'
Junio C Hamano [Mon, 16 Mar 2026 17:48:15 +0000 (10:48 -0700)] 
Merge branch 'jk/unleak-mmap'

Plug a few leaks where mmap'ed memory regions are not unmapped.

* jk/unleak-mmap:
  meson: turn on NO_MMAP when building with LSan
  Makefile: turn on NO_MMAP when building with LSan
  object-file: fix mmap() leak in odb_source_loose_read_object_stream()
  pack-revindex: avoid double-loading .rev files
  check_connected(): fix leak of pack-index mmap
  check_connected(): delay opening new_pack

3 weeks agoMerge branch 'ty/setup-error-tightening'
Junio C Hamano [Mon, 16 Mar 2026 17:48:14 +0000 (10:48 -0700)] 
Merge branch 'ty/setup-error-tightening'

While discovering a ".git" directory, the code treats any stat()
failure as a sign that a filesystem entity .git does not exist
there, and ignores ".git" that is not a "gitdir" file or a
directory.  The code has been tightened to notice and report
filesystem corruption better.

* ty/setup-error-tightening:
  setup: improve error diagnosis for invalid .git files

3 weeks agoMerge branch 'os/doc-git-custom-commands'
Junio C Hamano [Mon, 16 Mar 2026 17:48:14 +0000 (10:48 -0700)] 
Merge branch 'os/doc-git-custom-commands'

Doc update.

* os/doc-git-custom-commands:
  doc: make it easier to find custom command information

3 weeks agoMerge branch 'fp/t3310-unhide-git-failures'
Junio C Hamano [Mon, 16 Mar 2026 17:48:14 +0000 (10:48 -0700)] 
Merge branch 'fp/t3310-unhide-git-failures'

The construct 'test "$(command)" = expectation' loses the exit
status from the command, which has been fixed by breaking up the
statement into pieces.

* fp/t3310-unhide-git-failures:
  t3310: avoid hiding failures from rev-parse in command substitutions

3 weeks agoMerge branch 'jt/repo-structure-extrema'
Junio C Hamano [Mon, 16 Mar 2026 17:48:14 +0000 (10:48 -0700)] 
Merge branch 'jt/repo-structure-extrema'

"git repo structure" command learns to report maximum values on
various aspects of objects it inspects.

* jt/repo-structure-extrema:
  builtin/repo: find tree with most entries
  builtin/repo: find commit with most parents
  builtin/repo: add OID annotations to table output
  builtin/repo: collect largest inflated objects
  builtin/repo: add helper for printing keyvalue output
  builtin/repo: update stats for each object

3 weeks agoMerge branch 'sp/wt-status-wo-the-repository'
Junio C Hamano [Mon, 16 Mar 2026 17:48:13 +0000 (10:48 -0700)] 
Merge branch 'sp/wt-status-wo-the-repository'

Reduce dependence on the global the_hash_algo and the_repository
variables of wt-status code path.

* sp/wt-status-wo-the-repository:
  wt-status: use hash_algo from local repository instead of global the_hash_algo
  wt-status: replace uses of the_repository with local repository instances
  wt-status: pass struct repository through function parameters

3 weeks agodoc: fix git grep args order in Quick Reference
Guillaume Jacob [Mon, 16 Mar 2026 14:15:36 +0000 (14:15 +0000)] 
doc: fix git grep args order in Quick Reference

The example provided has its arguments in the wrong order. The revision
should follow the pattern, and not the other way around.

Signed-off-by: Guillaume Jacob <guillaume@absolut-sensing.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoclar: update to fix compilation on platforms without PATH_MAX
Patrick Steinhardt [Mon, 16 Mar 2026 07:50:43 +0000 (08:50 +0100)] 
clar: update to fix compilation on platforms without PATH_MAX

Update clar to e4172e3 (Merge pull request #134 from
clar-test/ethomson/const, 2026-01-10). Besides some changes to
"generate.py" which don't have any impact on us, this commit also fixes
compilation on platforms that don't have PATH_MAX, like for example
GNU/Hurd.

Reported-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agostash: do not pass strbuf by value
Deveshi Dwivedi [Sun, 15 Mar 2026 09:44:44 +0000 (09:44 +0000)] 
stash: do not pass strbuf by value

save_untracked_files() takes its 'files' parameter as struct strbuf
by value.  Passing a strbuf by value copies the struct but shares
the underlying buffer between caller and callee, risking a dangling
pointer and double-free if the callee reallocates.

The function needs both the buffer and its length for
pipe_command(), so a plain const char * is not sufficient here.
Switch the parameter to struct strbuf * and update the caller to
pass a pointer.

Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agococcinelle: detect struct strbuf passed by value
Deveshi Dwivedi [Sun, 15 Mar 2026 09:44:43 +0000 (09:44 +0000)] 
coccinelle: detect struct strbuf passed by value

Passing a struct strbuf by value to a function copies the struct
but shares the underlying character array between caller and callee.
If the callee causes a reallocation, the caller's copy becomes a
dangling pointer, leading to a double-free when strbuf_release() is
called.  There is no coccinelle rule to catch this pattern.

Jeff King suggested adding one during review of the
write_worktree_linking_files() fix [1], and noted that a reporting
rule using coccinelle's Python scripting extensions could emit a
descriptive warning, but we do not currently require Python support
in coccinelle.

Add a transformation rule that rewrites a by-value strbuf parameter
to a pointer.  The detection is identical to what a Python-based
reporting rule would catch; only the presentation differs.  The
resulting diff will not produce compilable code on its own (callers
and the function body still need updating), but the spatch output
alerts the developer that the signature needs attention.  This is
consistent with the other rules in strbuf.cocci, which also rewrite
to the preferred form.

[1] https://lore.kernel.org/git/20260309192600.GC309867@coredump.intra.peff.net/

Signed-off-by: Deveshi Dwivedi <deveshigurgaon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoMerge branch 'dd/list-objects-filter-options-wo-strbuf-split' into dd/cocci-do-not...
Junio C Hamano [Sun, 15 Mar 2026 21:46:30 +0000 (14:46 -0700)] 
Merge branch 'dd/list-objects-filter-options-wo-strbuf-split' into dd/cocci-do-not-pass-strbuf-by-value

* dd/list-objects-filter-options-wo-strbuf-split:
  list-objects-filter-options: avoid strbuf_split_str()
  worktree: do not pass strbuf by value

3 weeks agot/pack-refs-tests: use test_path_is_missing
Ritesh Singh Jadoun [Sun, 15 Mar 2026 08:10:32 +0000 (13:40 +0530)] 
t/pack-refs-tests: use test_path_is_missing

The pack-refs tests previously used raw 'test -f' and 'test -e' checks
with negation. Update them to use Git's standard helper function
test_path_is_missing for consistency and clearer failure reporting.

As suggested in review, replaced the negated 'test_path_exists' with
test_path_is_missing to better reflect the expected absence of paths.

Signed-off-by: Ritesh Singh Jadoun <riteshjd75@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agobuiltin/pack-objects: reduce lock contention when writing packfile data
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:21 +0000 (07:45 +0100)] 
builtin/pack-objects: reduce lock contention when writing packfile data

When running `git pack-objects --stdout` we feed the data through
`hashfd_ext()` with a progress meter and a smaller-than-usual buffer
length of 8kB so that we can track throughput more granularly. But as
packfiles tend to be on the larger side, this small buffer size may
cause a ton of write(3p) syscalls.

Originally, the buffer we used in `hashfd()` was 8kB for all use cases.
This was changed though in 2ca245f8be (csum-file.h: increase hashfile
buffer size, 2021-05-18) because we noticed that the number of writes
can have an impact on performance. So the buffer size was increased to
128kB, which improved performance a bit for some use cases.

But the commit didn't touch the buffer size for `hashd_throughput()`.
The reasoning here was that callers expect the progress indicator to
update frequently, and a larger buffer size would of course reduce the
update frequency especially on slow networks.

While that is of course true, there was (and still is, even though it's
now a call to `hashfd_ext()`) only a single caller of this function in
git-pack-objects(1). This command is responsible for writing packfiles,
and those packfiles are often on the bigger side. So arguably:

  - The user won't care about increments of 8kB when packfiles tend to
    be megabytes or even gigabytes in size.

  - Reducing the number of syscalls would be even more valuable here
    than it would be for multi-pack indices, which was the benchmark
    done in the mentioned commit, as MIDXs are typically significantly
    smaller than packfiles.

  - Nowadays, many internet connections should be able to transfer data
    at a rate significantly higher than 8kB per second.

Update the buffer to instead have a size of `LARGE_PACKET_DATA_MAX - 1`,
which translates to ~64kB. This limit was chosen because `git
pack-objects --stdout` is most often used when sending packfiles via
git-upload-pack(1), where packfile data is chunked into pktlines when
using the sideband. Furthermore, most internet connections should have a
bandwidth signifcantly higher than 64kB/s, so we'd still be able to
observe progress updates at a rate of at least once per second.

This change significantly reduces the number of write(3p) syscalls from
355,000 to 44,000 when packing the Linux repository. While this results
in a small performance improvement on an otherwise-unused system, this
improvement is mostly negligible. More importantly though, it will
reduce lock contention in the kernel on an extremely busy system where
we have many processes writing data at once.

Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agocsum-file: drop `hashfd_throughput()`
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:20 +0000 (07:45 +0100)] 
csum-file: drop `hashfd_throughput()`

The `hashfd_throughput()` function is used by a single callsite in
git-pack-objects(1). In contrast to `hashfd()`, this function uses a
progress meter to measure throughput and a smaller buffer length so that
the progress meter can provide more granular metrics.

We're going to change that caller in the next commit to be a bit more
specific to packing objects. As such, `hashfd_throughput()` will be a
somewhat unfitting mechanism for any potential new callers.

Drop the function and replace it with a call to `hashfd_ext()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agocsum-file: introduce `hashfd_ext()`
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:19 +0000 (07:45 +0100)] 
csum-file: introduce `hashfd_ext()`

Introduce a new `hashfd_ext()` function that takes an options structure.
This function will replace `hashd_throughput()` in the next commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agosideband: use writev(3p) to send pktlines
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:18 +0000 (07:45 +0100)] 
sideband: use writev(3p) to send pktlines

Every pktline that we send out via `send_sideband()` currently requires
two syscalls: one to write the pktline's length, and one to send its
data. This typically isn't all that much of a problem, but under extreme
load the syscalls may cause contention in the kernel.

Refactor the code to instead use the newly introduced writev(3p) infra
so that we can send out the data with a single syscall. This reduces the
number of syscalls from around 133,000 calls to write(3p) to around
67,000 calls to writev(3p).

Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agowrapper: introduce writev(3p) wrappers
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:17 +0000 (07:45 +0100)] 
wrapper: introduce writev(3p) wrappers

In the preceding commit we have added a compatibility wrapper for the
writev(3p) syscall. Introduce some generic wrappers for this function
that we nowadays take for granted in the Git codebase.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agocompat/posix: introduce writev(3p) wrapper
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:16 +0000 (07:45 +0100)] 
compat/posix: introduce writev(3p) wrapper

In a subsequent commit we're going to add the first caller to
writev(3p). Introduce a compatibility wrapper for this syscall that we
can use on systems that don't have this syscall.

The syscall exists on modern Unixes like Linux and macOS, and seemingly
even for NonStop according to [1]. It doesn't seem to exist on Windows
though.

[1]: http://nonstoptools.com/manuals/OSS-SystemCalls.pdf
[2]: https://www.gnu.org/software/gnulib/manual/html_node/writev.html

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoupload-pack: reduce lock contention when writing packfile data
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:15 +0000 (07:45 +0100)] 
upload-pack: reduce lock contention when writing packfile data

In our production systems we have recently observed write contention in
git-upload-pack(1). The system in question was consistently streaming
packfiles at a rate of dozens of gigabits per second, but curiously the
system was neither bottlenecked on CPU, memory or IOPS.

We eventually discovered that Git was spending 80% of its time in
`pipe_write()`, out of which almost all of the time was spent in the
`ep_poll_callback` function in the kernel. Quoting the reporter:

  This infrastructure is part of an event notification queue designed to
  allow for multiple producers to emit events, but that concurrency
  safety is guarded by 3 layers of locking. The layer we're hitting
  contention in uses a simple reader/writer lock mode (a.k.a. shared
  versus exclusive mode), where producers need shared-mode (read mode),
  and various other actions use exclusive (write) mode.

The system in question generates workloads where we have hundreds of
git-upload-pack(1) processes active at the same point in time. These
processes end up contending around those locks, and the consequence is
that the Git processes stall.

Now git-upload-pack(1) already has the infrastructure in place to buffer
some of the data it reads from git-pack-objects(1) before actually
sending it out. We only use this infrastructure in very limited ways
though, so we generally end up matching one read(3p) call with one
write(3p) call. Even worse, when the sideband is enabled we end up
matching one read with _two_ writes: one for the pkt-line length, and
one for the packfile data.

Extend our use of the buffering infrastructure so that we soak up bytes
until the buffer is filled up at least 2/3rds of its capacity. The
change is relatively simple to implement as we already know to flush the
buffer in `create_pack_file()` after git-pack-objects(1) has finished.

This significantly reduces the number of write(3p) syscalls we need to
do. Before this change, cloning the Linux repository resulted in around
400,000 write(3p) syscalls. With the buffering in place we only do
around 130,000 syscalls.

Now we could of course go even further and make sure that we always fill
up the whole buffer. But this might cause an increase in read(3p)
syscalls, and some tests show that this only reduces the number of
write(3p) syscalls from 130,000 to 100,000. So overall this doesn't seem
worth it.

Note that the issue could also be fixed by adapting the write buffer
that we use in the downstream git-pack-objects(1) command, and such a
change would have roughly the same result. But the command that
generates the packfile data may not always be git-pack-objects(1) as it
can be changed via "uploadpack.packObjectsHook", so such a fix would
only help in _some_ cases. Regardless of that, we'll also adapt the
write buffer size of git-pack-objects(1) in a subsequent commit.

Helped-by: Matt Smiley <msmiley@gitlab.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoupload-pack: prefer flushing data over sending keepalive
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:14 +0000 (07:45 +0100)] 
upload-pack: prefer flushing data over sending keepalive

When using the sideband in git-upload-pack(1) we know to send out
keepalive packets in case generating the pack takes too long. These
keepalives take the form of a simple empty pktline.

In the preceding commit we have adapted git-upload-pack(1) to buffer
data more aggressively before sending it to the client. This creates an
obvious optimization opportunity: when we hit the keepalive timeout
while we still hold on to some buffered data, then it makes more sense
to flush out the data instead of sending the empty keepalive packet.

This is overall not going to be a significant win. Most keepalives will
come before the pack data starts, and once pack-objects starts producing
data, it tends to do so pretty consistently. And of course we can't send
data before we see the PACK header, because the whole point is to buffer
the early bit waiting for packfile URIs. But the optimization is easy
enough to realize.

Do so and flush out data instead of sending an empty pktline.

Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 weeks agoupload-pack: adapt keepalives based on buffering
Patrick Steinhardt [Fri, 13 Mar 2026 06:45:13 +0000 (07:45 +0100)] 
upload-pack: adapt keepalives based on buffering

The function `create_pack_file()` is responsible for sending the
packfile data to the client of git-upload-pack(1). As generating the
bytes may take significant computing resources we also have a mechanism
in place that optionally sends keepalive pktlines in case we haven't
sent out any data.

The keepalive logic is purely based poll(3p): we pass a timeout to that
syscall, and if the call times out we send out the keepalive pktline.
While reasonable, this logic isn't entirely sufficient: even if the call
to poll(3p) ends because we have received data on any of the file
descriptors we may not necessarily send data to the client.

The most important edge case here happens in `relay_pack_data()`. When
we haven't seen the initial "PACK" signature from git-pack-objects(1)
yet we buffer incoming data. So in the worst case, if each of the bytes
of that signature arrive shortly before the configured keepalive
timeout, then we may not send out any data for a time period that is
(almost) four times as long as the configured timeout.

This edge case is rather unlikely to matter in practice. But in a
subsequent commit we're going to adapt our buffering mechanism to become
more aggressive, which makes it more likely that we don't send any data
for an extended amount of time.

Adapt the logic so that instead of using a fixed timeout on every call
to poll(3p), we instead figure out how much time has passed since the
last-sent data.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 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>
3 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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

4 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

4 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

4 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>
4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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>
4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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

4 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>