]> Kevux Git Server - rit/log
rit
7 weeks agoremote: add remote.*.negotiationInclude config
Derrick Stolee [Tue, 19 May 2026 16:24:54 +0000 (16:24 +0000)]
remote: add remote.*.negotiationInclude config

Add a new 'remote.<name>.negotiationInclude' multi-valued config option that
provides default values for --negotiation-include when no
--negotiation-include arguments are specified over the command line.  This
is a mirror of how 'remote.<name>.negotiationRestrict' specifies defaults
for the --negotiation-restrict arguments.

Each value is either an exact ref name or a glob pattern whose tips should
always be sent as 'have' lines during negotiation. The config values are
resolved through the same resolve_negotiation_include() codepath as the CLI
options.

This option is additive with the normal negotiation process: the negotiation
algorithm still runs and advertises its own selected commits, but the refs
matching the config are sent unconditionally on top of those heuristically
selected commits.

Similar to the negotiationRestrict config, an empty value resets the value
list to allow ignoring earlier config values, such as those that might be
set in system or global config.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agofetch: add --negotiation-include option for negotiation
Derrick Stolee [Tue, 19 May 2026 16:24:53 +0000 (16:24 +0000)]
fetch: add --negotiation-include option for negotiation

Add a new --negotiation-include option to 'git fetch', which ensures
that certain ref tips are always sent as 'have' lines during fetch
negotiation, regardless of what the negotiation algorithm selects.

This is useful when the repository has a large number of references, so
the normal negotiation algorithm truncates the list. This is especially
important in repositories with long parallel commit histories. For
example, a repo could have a 'dev' branch for development and a
'release' branch for released versions. If the 'dev' branch isn't
selected for negotiation, then it's not a big deal because there are
many in-progress development branches with a shared history. However, if
'release' is not selected for negotiation, then the server may think
that this is the first time the client has asked for that reference,
causing a full download of its parallel commit history (and any extra
data that may be unique to that branch). This is based on a real example
where certain fetches would grow to 60+ GB when a release branch
updated.

This option is a complement to --negotiation-restrict, which reduces the
negotiation ref set to a specific list. In the earlier example, using
--negotiation-restrict to focus the negotiation to 'dev' and 'release'
would avoid those problematic downloads, but would still not allow
advertising potentially-relevant user branches. In this way, the
'include' version solves the problem I mention while allowing
negotiation to pick other references opportunistically. The two options
can also be combined to allow the best of both worlds.

The argument may be an exact ref name or a glob pattern. Non-existent
refs are silently ignored. This behavior is also updated in the ref matching
logic for the related --negotiation-restrict option to match.

The implementation outputs the requested objects as haves before the
negotiator performs its own algorithm to choose the next haves. Use the new
have_sent() interface to signal these have commits were sent before engaging
with the negotiator's next() iterator.

Also add --negotiation-include to 'git pull' passthrough options.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agonegotiator: add have_sent() interface
Derrick Stolee [Tue, 19 May 2026 16:24:52 +0000 (16:24 +0000)]
negotiator: add have_sent() interface

In a future change, we will introduce a capability to choose specific commit
OIDs as 'have's in fetch negotiation, with the ability to have the
negotiator choose more 'have's to increase coverage beyond that required
core set. The negotiator works to avoid emitting 'have's that can reach each
other, but that logic is hidden beneath the negotiator's iterator function
pointer ('next'). We need a way to communicate to the negotiator that we
have picked a 'have' so it could incorporate that into its logic.

Add a have_sent() method to the fetch_negotiator interface. This is the
signal that allows the negotiator to track the commit as already shown and
can perform the proper bookkeeping to avoid emitting those objects or
anything they can reach.

For our non-trivial negotiators, it is sufficient to mark these commits as
common, so the implementation is quite simple. This logic will be exercised
in the next change.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agoremote: add remote.*.negotiationRestrict config
Derrick Stolee [Tue, 19 May 2026 16:24:51 +0000 (16:24 +0000)]
remote: add remote.*.negotiationRestrict config

In a previous change, the --negotiation-restrict command-line option of 'git
fetch' was added as a synonym of --negotiation-tip. Both of these options
restrict the set of 'haves' the client can send as part of negotiation.

This was previously not available via a configuration option. Add a new
'remote.<name>.negotiationRestrict' multi-valued config option that updates
'git fetch <name>' to use these restrictions by default.

If the user provides even one --negotiation-restrict argument, then the
config is ignored.

An empty value resets the value list to allow ignoring earlier config
values, such as those that might be set in system or global config.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agotransport: rename negotiation_tips
Derrick Stolee [Tue, 19 May 2026 16:24:50 +0000 (16:24 +0000)]
transport: rename negotiation_tips

The previous change added the --negotiation-restrict synonym for the
--negotiation-tip option for 'git fetch'. In anticipation of adding a new
option that behaves similarly but with distinct changes to its behavior,
rename the internal representation of this data from 'negotiation_tips' to
'negotiation_restrict_tips'.

The 'tips' part is kept because this is an oid_array in the transport layer.
This requires the builtin to handle parsing refs into collections of oids so
the transport layer can handle this cleaner form of the data.

Also update the string_list used to store the inputs from command-line
options.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agofetch: add --negotiation-restrict option
Derrick Stolee [Tue, 19 May 2026 16:24:49 +0000 (16:24 +0000)]
fetch: add --negotiation-restrict option

The --negotiation-tip option to 'git fetch' and 'git pull' allows users
to specify that they want to focus negotiation on a small set of
references. This is a _restriction_ on the negotiation set, helping to
focus the negotiation when the ref count is high. However, it doesn't
allow for the ability to opportunistically select references beyond that
list.

This subtle detail that this is a 'maximum set' and not a 'minimum set'
is not immediately clear from the option name. This makes it more
complicated to add a new option that provides the complementary behavior
of a minimum set.

For now, create a new synonym option, --negotiation-restrict, that
behaves identically to --negotiation-tip. Update the documentation to
make it clear that this new name is the preferred option, but we keep
the old name for compatibility. Mark --negotiation-tip as an alias of the
new, preferred option.

Update a few warning messages with the new option, but also make them
translatable with the option name inserted by formatting. At least one
of these messages will be reused later for a new option.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agot5516: fix test order flakiness
Derrick Stolee [Tue, 19 May 2026 16:24:48 +0000 (16:24 +0000)]
t5516: fix test order flakiness

The 'fetch follows tags by default' test sorts using 'sort -k 4', but
for-each-ref output only has 3 columns. This relies on sort treating records
with fewer fields as having an empty fourth field, which may produce
unstable results depending on locale. This appears to be an accident added
in 3f763ddf28 (fetch: set remote/HEAD if it does not exist, 2024-11-22).

Use 'sort -k 3' to match the actual number of columns in the output.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 months agoMerge branch 'master' of https://github.com/j6t/git-gui
Junio C Hamano [Sat, 21 Mar 2026 16:25:58 +0000 (09:25 -0700)]
Merge branch 'master' of https://github.com/j6t/git-gui

* 'master' of https://github.com/j6t/git-gui:
  git-gui: grey out comment lines in commit message
  git-gui: wire up "git-gui--askyesno" with Meson
  git-gui: massage "git-gui--askyesno" with "generate-script.sh"
  git-gui: prefer shell at "/bin/sh" with Meson
  git-gui: fix use of GIT_CEILING_DIRECTORIES
  git-gui: shift tabstops to account for the first column of patch text

3 months agoMerge branch 'master' of https://github.com/j6t/gitk
Junio C Hamano [Sat, 21 Mar 2026 16:25:10 +0000 (09:25 -0700)]
Merge branch 'master' of https://github.com/j6t/gitk

* 'master' of https://github.com/j6t/gitk:
  gitk: l10n: make PO headers identify the Gitk project
  gitk: ignore generated POT file
  gitk: i18n: use "Gitk" as package name in POT file
  gitk: commit translation files without file information
  gitk: support link color in the Preferences dialog
  gitk: use config settings for head/tag colors

3 months agoMerge branch 'jx/i18n-fix' of github.com:jiangxin/gitk
Johannes Sixt [Fri, 20 Mar 2026 08:23:32 +0000 (09:23 +0100)]
Merge branch 'jx/i18n-fix' of github.com:jiangxin/gitk

* 'jx/i18n-fix' of github.com:jiangxin/gitk:
  gitk: l10n: make PO headers identify the Gitk project
  gitk: ignore generated POT file
  gitk: i18n: use "Gitk" as package name in POT file

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
3 months agoMerge branch 'js/i18n-no-location'
Johannes Sixt [Fri, 20 Mar 2026 08:18:19 +0000 (09:18 +0100)]
Merge branch 'js/i18n-no-location'

* js/i18n-no-location:
  gitk: commit translation files without file information

3 months agoMerge branch 'sb/heed-ref-decoration-settings'
Johannes Sixt [Fri, 20 Mar 2026 08:07:09 +0000 (09:07 +0100)]
Merge branch 'sb/heed-ref-decoration-settings'

* sb/heed-ref-decoration-settings:
  gitk: use config settings for head/tag colors

3 months agogitk: l10n: make PO headers identify the Gitk project
Jiang Xin [Thu, 19 Mar 2026 09:11:17 +0000 (17:11 +0800)]
gitk: l10n: make PO headers identify the Gitk project

Commit f697d08 (gitk: i18n: use "Gitk" as package name in POT file,
2026-03-19) updated the generated POT template to use "Gitk" in its
Project-Id-Version header. Several existing PO files still carry older
header values such as "git" or "git-gui", so they do not consistently
identify themselves as Gitk translations.

Update the Project-Id-Version field in all Gitk PO files so that they
identify the Gitk project consistently.

The "Project-Id-Version" field in the PO header helps tools identify
which project a PO file belongs to. For example, Git's
"git-po-helper" uses it to choose project-specific checks and POT
handling rules. Without this change, some Gitk PO files are
misidentified because their headers still refer to other projects.

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
3 months agogitk: ignore generated POT file
Jiang Xin [Thu, 19 Mar 2026 09:08:47 +0000 (17:08 +0800)]
gitk: ignore generated POT file

"po/gitk.pot" is generated from the source for translation maintenance.
Ignore it in the working tree so regenerating the template does not
introduce unnecessary noise in `git status`.

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
3 months agogitk: i18n: use "Gitk" as package name in POT file
Jiang Xin [Thu, 19 Mar 2026 09:06:25 +0000 (17:06 +0800)]
gitk: i18n: use "Gitk" as package name in POT file

Use "Gitk" instead of the placeholder "PACKAGE" in the header of the
generated po/gitk.pot file. In particular, the "Project-Id-Version"
field in the header entry should be set to:

    "Project-Id-Version: Gitk\n"

New PO files generated from this POT file will inherit that package
name.

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
3 months agoThe 18th batch
Junio C Hamano [Thu, 19 Mar 2026 16:54:41 +0000 (09:54 -0700)]
The 18th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 months agoMerge branch 'ss/submodule--helper-use-xmalloc'
Junio C Hamano [Thu, 19 Mar 2026 16:54:56 +0000 (09:54 -0700)]
Merge branch 'ss/submodule--helper-use-xmalloc'

Code clean-up.

* ss/submodule--helper-use-xmalloc:
  submodule--helper: replace malloc with xmalloc

3 months agoMerge branch 'ps/unit-test-c-escape-names.txt'
Junio C Hamano [Thu, 19 Mar 2026 16:54:56 +0000 (09:54 -0700)]
Merge branch 'ps/unit-test-c-escape-names.txt'

The unit test helper function was taught to use backslash +
mnemonic notation for certain control characters like "\t", instead
of octal notation like "\011".

* ps/unit-test-c-escape-names.txt:
  test-lib: print escape sequence names

3 months agoMerge branch 'jc/doc-wholesale-replace-before-next'
Junio C Hamano [Thu, 19 Mar 2026 16:54:56 +0000 (09:54 -0700)]
Merge branch 'jc/doc-wholesale-replace-before-next'

Doc update.

* jc/doc-wholesale-replace-before-next:
  SubmittingPatches: spell out "replace fully to pretend to be perfect"

3 months agoMerge branch 'lc/rebase-trailer'
Junio C Hamano [Thu, 19 Mar 2026 16:54:56 +0000 (09:54 -0700)]
Merge branch 'lc/rebase-trailer'

"git rebase" learns "--trailer" command to drive the
interpret-trailers machinery.

* lc/rebase-trailer:
  rebase: support --trailer
  commit, tag: parse --trailer with OPT_STRVEC
  trailer: append trailers without fork/exec
  trailer: libify a couple of functions
  interpret-trailers: refactor create_in_place_tempfile()
  interpret-trailers: factor trailer rewriting

3 months agoMerge branch 'bk/run-command-wo-the-repository'
Junio C Hamano [Thu, 19 Mar 2026 16:54:55 +0000 (09:54 -0700)]
Merge branch 'bk/run-command-wo-the-repository'

The run_command() API lost its implicit dependencyon the singleton
`the_repository` instance.

* bk/run-command-wo-the-repository:
  run-command: wean auto_maintenance() functions off the_repository
  run-command: wean start_command() off the_repository

3 months agoMerge branch 'ps/editorconfig-unanchor'
Junio C Hamano [Thu, 19 Mar 2026 16:54:55 +0000 (09:54 -0700)]
Merge branch 'ps/editorconfig-unanchor'

Editorconfig filename patterns were specified incorrectly, making
many source files inside subdirectories unaffected, which has been
corrected.

* ps/editorconfig-unanchor:
  editorconfig: fix style not applying to subdirs anymore

3 months agoMerge branch 'ss/t3200-test-zero-oid'
Junio C Hamano [Thu, 19 Mar 2026 16:54:55 +0000 (09:54 -0700)]
Merge branch 'ss/t3200-test-zero-oid'

A test now uses the symbolic constant $ZERO_OID instead of 40 "0" to
work better with SHA-256 as well as SHA-1.

* ss/t3200-test-zero-oid:
  t3200: replace hardcoded null OID with $ZERO_OID

3 months agoMerge branch 'dd/list-objects-filter-options-wo-strbuf-split'
Junio C Hamano [Thu, 19 Mar 2026 16:54:55 +0000 (09:54 -0700)]
Merge branch 'dd/list-objects-filter-options-wo-strbuf-split'

The way combined list-object filter options are parsed has been
revamped.

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

3 months agoMerge branch 'ps/t9200-test-path-is-helpers'
Junio C Hamano [Thu, 19 Mar 2026 16:54:54 +0000 (09:54 -0700)]
Merge branch 'ps/t9200-test-path-is-helpers'

Test update.

* ps/t9200-test-path-is-helpers:
  t9200: replace test -f with modern path helper
  t9200: handle missing CVS with skip_all

3 months 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 months 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 months 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 months 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 months 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 months 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 months 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 months 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 months 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

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

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

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

4 months 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()`

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

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