]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
4 weeks agoxdiff: reduce the size of array
Phillip Wood [Mon, 4 May 2026 14:06:21 +0000 (15:06 +0100)] 
xdiff: reduce the size of array

When the myers algorithm is selected the input files are pre-processed
to remove any common prefix and suffix and any lines that appear
in only one file. This requires a map to be created between the
lines that are processed by the myers algorithm and the lines in
the original file. That map does not include the common lines at the
beginning and end of the files but the array is allocated to be the
size of the whole file. Move the allocation into xdl_cleanup_records()
where the map is populated and we know how big it needs to be.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 weeks agoxprepare: simplify error handling
Phillip Wood [Mon, 4 May 2026 14:06:20 +0000 (15:06 +0100)] 
xprepare: simplify error handling

If either of the two allocations fail we want to take the same action
so use a single if statement. This saves a few lines and makes it
easier for the next commit to add a couple more allocations.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 weeks agoxdiff: cleanup xdl_clean_mmatch()
Phillip Wood [Mon, 4 May 2026 14:06:19 +0000 (15:06 +0100)] 
xdiff: cleanup xdl_clean_mmatch()

Remove the "s" parameter as, since the last commit, this function
is always called with s == 0. Also change parameter "e" to expect a
length, rather than the index of the last line to simplify the caller.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 weeks agoxdiff: reduce size of action arrays
Phillip Wood [Mon, 4 May 2026 14:06:18 +0000 (15:06 +0100)] 
xdiff: reduce size of action arrays

When the myers algorithm is selected the input files are pre-processed
to remove any common prefix and suffix. Then any lines that appear
only in one side of the diff are marked as changed and frequently
occurring lines are marked as changed if they are adjacent to a
changed line. This step requires a couple of temporary arrays. As as
the common prefix and suffix have already been removed, the arrays
only need to be big enough to hold the lines between them, not the
whole file. Reduce the size of the arrays and adjust the loops that
use them accordingly while taking care to keep indexing the arrays
in xdfile_t with absolute line numbers.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 weeks agoMerge branch 'en/xdiff-cleanup-3' into pw/xdiff-shrink-memory-consumption
Junio C Hamano [Tue, 5 May 2026 07:19:59 +0000 (16:19 +0900)] 
Merge branch 'en/xdiff-cleanup-3' into pw/xdiff-shrink-memory-consumption

* en/xdiff-cleanup-3:
  xdiff/xdl_cleanup_records: make execution of action easier to follow
  xdiff/xdl_cleanup_records: make setting action easier to follow
  xdiff/xdl_cleanup_records: make limits more clear
  xdiff/xdl_cleanup_records: use unambiguous types
  xdiff: use unambiguous types in xdl_bogo_sqrt()
  xdiff/xdl_cleanup_records: delete local recs pointer

5 weeks agoworktree: rename get_worktree_from_repository()
Phillip Wood [Fri, 1 May 2026 15:20:00 +0000 (16:20 +0100)] 
worktree: rename get_worktree_from_repository()

get_worktree_from_repository() returns a struct worktree that
describes the worktree that the repository argument would operate
on. Since 0f779147602 (worktree: remove "the_repository" from
is_current_worktree(), 2026-03-26) that worktree is always the
"current" worktree. Change the name to get_current_worktee() to
reflect better what the function does.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agodoc: clarify http.emptyAuth values
Matthew John Cheetham [Thu, 30 Apr 2026 10:54:32 +0000 (10:54 +0000)] 
doc: clarify http.emptyAuth values

The existing description of http.emptyAuth explains the purpose of the
setting but never says what values it accepts. Readers have to infer
from context (or read the source) that it takes 'true', 'false', or
'auto', and what each one means.

Document the three accepted values explicitly:

* 'auto' (the default) only sends empty credentials when the server's
  401 response advertises a mechanism that requires them, such as
  GSS-Negotiate. This matches the long-standing auto-detection
  behaviour added in 40a18fc77c (http: add an "auto" mode for
  http.emptyauth, 2017-02-25).

* 'true' unconditionally sends empty credentials on the very first
  request, before any 401 response, for callers that know they want
  this behaviour up front.

* 'false' disables the feature entirely; mechanisms that depend on
  empty credentials, such as GSS-Negotiate, will not work in this
  mode.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agol10n: bump mshick/add-pr-comment from v2 to v3
Johannes Schindelin [Thu, 30 Apr 2026 07:35:00 +0000 (07:35 +0000)] 
l10n: bump mshick/add-pr-comment from v2 to v3

The l10n workflow uses `mshick/add-pr-comment` to post git-po-helper
reports as comments on translation pull requests. It was still pinned
to v2, which runs on Node.js 20. GitHub is phasing out the Node.js 20
runtime on Actions runners, so staying on v2 will eventually cause the
"Create comment in pull request for report" step to fail.

The sole breaking change in v3 is the switch from Node.js 20 to
Node.js 24 (https://github.com/mshick/add-pr-comment/releases/tag/v3.0.0).
The action's inputs and outputs are unchanged, so the upgrade is a
drop-in replacement. Subsequent v3.x releases added new opt-in
features (message truncation, retry with exponential backoff, file
attachments, commit comment support, "delete on status") but none of
them affect existing callers that do not opt in.

See also:

- Changelog: https://github.com/mshick/add-pr-comment/blob/main/CHANGELOG.md
- Compare: https://github.com/mshick/add-pr-comment/compare/v2...v3

Pointed-out-by: Christoph Grüninger <foss@grueninger.de>
Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoci: bump git-for-windows/setup-git-for-windows-sdk from v1 to v2
Johannes Schindelin [Thu, 30 Apr 2026 07:34:59 +0000 (07:34 +0000)] 
ci: bump git-for-windows/setup-git-for-windows-sdk from v1 to v2

The v1 of `git-for-windows/setup-git-for-windows-sdk` runs on
Node.js 20, which GitHub is phasing out of the Actions runners.
v2 moves the action to Node.js 24 so that the CI jobs relying on
a Git for Windows SDK keep working once Node.js 20 is removed.

The risk is very low: v2 contains no functional changes to the
SDK setup itself, only the runtime upgrade. The action still
provisions the same minimal SDK and exposes the same outputs.
The sole precondition is a recent Actions Runner (>= 2.327.1),
which the github.com-hosted runners already satisfy.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoci: bump actions/checkout from v5 to v6
Johannes Schindelin [Thu, 30 Apr 2026 07:34:58 +0000 (07:34 +0000)] 
ci: bump actions/checkout from v5 to v6

Every workflow currently pins `actions/checkout` to v5, which was
introduced primarily to move to the Node.js 24 runtime. v6 is the
next release and worth picking up so we stay on a maintained version
of the action.

The one behaviorally interesting change in v6:

  `persist-credentials` now stores the helper credentials under
  `$RUNNER_TEMP` instead of writing them directly into the local
  `.git/config`. Two implications follow:

  1. In the normal case this is an unambiguous improvement -- the
     token no longer lands in `.git/config`, reducing the risk of
     inadvertently leaking it through workspace archiving
     (`upload-artifact` snapshots, cache entries, core dumps, ...).

  2. Docker container actions require an Actions Runner of at least
     v2.329.0 to find the credentials in their new location. The
     github.com-hosted runners our CI uses are already past that
     version, so this does not affect us. Downstream users running
     self-hosted runners may need to update them before adopting
     this version of the action.

Risk analysis: our checkout steps either check out the default
repository (no special credential requirements) or, in the `vs-build`
job, explicitly set `repository: microsoft/vcpkg` and
`path: compat/vcbuild/vcpkg`. Neither case relies on the precise
location of the persisted credentials -- subsequent steps interact
with the API via the runner-provided `GITHUB_TOKEN` directly -- so
the v6 credential-storage change is transparent to our workflows.
The diff is purely the `@vN` identifier; there are no input or
output changes.

See also:

- Release notes: https://github.com/actions/checkout/releases
- Changelog: https://github.com/actions/checkout/blob/main/CHANGELOG.md
- Compare: https://github.com/actions/checkout/compare/v5...v6

Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoci: bump actions/github-script from v8 to v9
Johannes Schindelin [Thu, 30 Apr 2026 07:34:57 +0000 (07:34 +0000)] 
ci: bump actions/github-script from v8 to v9

The only use we have of `actions/github-script` is the "skip if the
commit or tree was already tested" step in `main.yml`, which checks
whether an identical tree-SHA was already built successfully. It
currently pins v8; v9 is the latest release.

What v9 changes:

- The `ACTIONS_ORCHESTRATION_ID` environment variable is now
  appended to the HTTP user-agent string. This is transparent to
  our script.
- A new injected `getOctokit` factory lets scripts create
  additional authenticated clients in the same step without
  importing `@actions/github`. We do not use it.
- Two breaking changes affect scripts that either call
  `require('@actions/github')` (fails at runtime, because
  `@actions/github` v9 is now ESM-only) or that shadow the
  implicit `getOctokit` parameter via `const`/`let` (syntax
  error). Our script does neither -- it only uses the pre-supplied
  `github` REST client and `core` helpers -- so the upgrade is
  safe.

Risk analysis: the step is advisory. It sets `enabled=' but skip'`
as an optimization to avoid re-running CI on a tree that was already
tested successfully. Even if the v9 upgrade broke the script, the
surrounding `try { ... } catch (e) { core.warning(e); }` block would
degrade it to a warning and CI would still run normally. In practice
the script continues to work identically on v9.

See also:

- Release notes: https://github.com/actions/github-script/releases
- Compare: https://github.com/actions/github-script/compare/v8...v9

Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoci: bump actions/{upload,download}-artifact to v7 and v8
Johannes Schindelin [Thu, 30 Apr 2026 07:34:56 +0000 (07:34 +0000)] 
ci: bump actions/{upload,download}-artifact to v7 and v8

`actions/upload-artifact` and `actions/download-artifact` are tightly
coupled: the upload action writes artifact archives in a format that
the download action then reads. Because of this coupling, the two
actions should always be bumped together so that the artifact format
contract between them is satisfied.

All of our `actions/upload-artifact` uses are still on v5, with one
stray v4 occurrence. Keeping them on these versions would leave the
artifact-upload steps running on Node.js 20, which GitHub is phasing
out, and would eventually cause all upload steps to fail.

Going from v5 directly to v7 folds in two release bumps:

- v6 switches the action's default runtime from Node.js 20 to
  Node.js 24 (v5 had preliminary Node 24 support but still defaulted
  to Node 20). This is the main motivation for bumping now: it gets
  us off the deprecated runtime.
- v7 adds two opt-in features: direct (unzipped) single-file uploads
  via a new `archive: false` parameter, and an internal conversion of
  the action to ESM to match the updated `@actions/*` packages.

Risk analysis: we never pass `archive`, so the zip-as-usual behavior
is unchanged. We also do not `require('@actions/*')` from any calling
workflow, so the ESM migration cannot affect us. The upload steps we
care about -- tracked files/build artifacts and failing-test
directories -- keep the same inputs (`name`, `path`) and outputs, so
the diff is purely the `@vN` identifier. The main precondition is a
recent Actions Runner (>= 2.327.1), which the github.com-hosted
runners used by our CI already satisfy.

While at it, align the one remaining `@v4` occurrence with the rest
so that every `upload-artifact` step uses the same version.

See also:

- Release notes: https://github.com/actions/upload-artifact/releases
- Compare: https://github.com/actions/upload-artifact/compare/v5...v7

We use `actions/download-artifact` to pass build artifacts between
the "windows-build" / "vs-build" / "windows-meson-build" jobs and
their corresponding test jobs. All callers are currently on v6;
bumping to v8 keeps this action in lockstep with the `upload-artifact`
bump above.

What v7 and v8 change:

- v7 switches the default runtime from Node.js 20 to Node.js 24 (v6
  had preliminary Node 24 support but still defaulted to Node 20).
  This is the main motivation: it gets us off the deprecated runtime.
- v8 makes three further changes:
  * The package is converted to ESM (invisible to workflow authors).
  * The action now checks the `Content-Type` header before
    attempting to unzip a download, so that directly-uploaded
    (unzipped) artifacts from `upload-artifact` v7 are downloaded
    correctly.
  * The `digest-mismatch` behaviour is changed from warn-and-
    continue to a hard failure by default.

Risk analysis: defaulting hash-mismatch to a hard failure is
strictly safer than the previous warn-and-continue behaviour -- a
mismatch points to real corruption or tampering and should stop the
run. We download archives that the same workflow just uploaded, on
the same runner fleet, so false positives are not expected. Our
usage is limited to the `name` and `path` inputs, which are
unchanged between v6 and v8, so the diff is purely the `@vN`
identifier.

See also:

- Release notes: https://github.com/actions/download-artifact/releases
- Compare: https://github.com/actions/download-artifact/compare/v6...v8

Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoci: bump microsoft/setup-msbuild from v2 to v3
Johannes Schindelin [Thu, 30 Apr 2026 07:34:55 +0000 (07:34 +0000)] 
ci: bump microsoft/setup-msbuild from v2 to v3

The v2 of `microsoft/setup-msbuild` runs on Node.js 20, which GitHub
is phasing out of the Actions runners. v3 is a minimal release whose
only substantive change is moving the action's runtime to Node.js 24,
so that our Visual Studio build jobs keep working once Node.js 20 is
removed from the runners.

The risk of this bump is very low: v3 contains no functional changes
to the action itself -- it merely adds `msbuild.exe` to `PATH`, with
no change to command-line flags, inputs, outputs, or default tool
resolution. The only precondition is a recent-enough Actions Runner,
which the github.com-hosted runners already satisfy.

See also:

- Release notes: https://github.com/microsoft/setup-msbuild/releases
- Compare: https://github.com/microsoft/setup-msbuild/compare/v2...v3

Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoxdiff/xdl_cleanup_records: make execution of action easier to follow
Ezekiel Newren [Wed, 29 Apr 2026 22:08:15 +0000 (22:08 +0000)] 
xdiff/xdl_cleanup_records: make execution of action easier to follow

Helped-by: Phillip Wood
Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoxdiff/xdl_cleanup_records: make setting action easier to follow
Ezekiel Newren [Wed, 29 Apr 2026 22:08:14 +0000 (22:08 +0000)] 
xdiff/xdl_cleanup_records: make setting action easier to follow

Rewrite nested ternaries with a clear if/else ladder for
action1/action2 to improve readability while preserving
behavior.

Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoxdiff/xdl_cleanup_records: make limits more clear
Ezekiel Newren [Wed, 29 Apr 2026 22:08:13 +0000 (22:08 +0000)] 
xdiff/xdl_cleanup_records: make limits more clear

Make the handling of per-file limits and the minimal-case clearer.
  * Use explicit per-file limit variables (mlim1, mlim2) and initialize
    them.
  * The additional condition `!need_min` is redudant now, remove it.
Best viewed with --color-words.

Helped-by: Phillip Wood
Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoxdiff/xdl_cleanup_records: use unambiguous types
Ezekiel Newren [Wed, 29 Apr 2026 22:08:12 +0000 (22:08 +0000)] 
xdiff/xdl_cleanup_records: use unambiguous types

Change the parameters of xdl_clean_mmatch() and the local variables
i, nm, mlim in xdl_cleanup_records() to use unambiguous types. Best
viewed with --color-words.

Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoxdiff: use unambiguous types in xdl_bogo_sqrt()
Ezekiel Newren [Wed, 29 Apr 2026 22:08:11 +0000 (22:08 +0000)] 
xdiff: use unambiguous types in xdl_bogo_sqrt()

There is no real square root for a negative number and size_t may not
be large enough for certain applications, replace long with uint64_t.

Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoxdiff/xdl_cleanup_records: delete local recs pointer
Ezekiel Newren [Wed, 29 Apr 2026 22:08:10 +0000 (22:08 +0000)] 
xdiff/xdl_cleanup_records: delete local recs pointer

Simplify the first 2 for loops by directly indexing the xdfile.recs.
recs is unused in the last 2 for loops, remove it. Best viewed with
--color-words.

Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agocheckout -m: autostash when switching branches
Harald Nordgren [Tue, 28 Apr 2026 18:39:12 +0000 (18:39 +0000)] 
checkout -m: autostash when switching branches

When switching branches with "git checkout -m", the attempted merge
of local modifications may cause conflicts with the changes made on
the other branch, which the user may not want to (or may not be able
to) resolve right now.  Because there is no easy way to recover from
this situation, we discouraged users from using "checkout -m" unless
they are certain their changes are trivial and within their ability
to resolve conflicts.

Teach the -m flow to create a temporary stash before switching and
reapply it after.  On success, the stash is silently applied and
the list of locally modified paths is shown, same as a successful
"git checkout" without "-m".

If reapplying causes conflicts, the stash is kept and the user is
told they can resolve and run "git stash drop", or run "git reset
--hard" and later "git stash pop" to recover their changes.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agocheckout: rollback lock on early returns in merge_working_tree
Harald Nordgren [Tue, 28 Apr 2026 18:39:11 +0000 (18:39 +0000)] 
checkout: rollback lock on early returns in merge_working_tree

merge_working_tree() acquires the index lock via
repo_hold_locked_index() but several early return paths exit
without calling rollback_lock_file(), leaving the lock held.
While this is currently harmless because the process exits soon
after, it becomes a problem if the function is ever called more
than once in the same process.

Add rollback_lock_file() calls to all early return paths.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agosequencer: teach autostash apply to take optional conflict marker labels
Harald Nordgren [Tue, 28 Apr 2026 18:39:10 +0000 (18:39 +0000)] 
sequencer: teach autostash apply to take optional conflict marker labels

Add label_ours, label_theirs, label_base, and stash_msg parameters to
apply_autostash_ref() and the autostash apply machinery so callers can
pass custom conflict marker labels through to
"git stash apply --label-ours/--label-theirs/--label-base", as well as
a custom stash message for "git stash store -m".

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agosequencer: allow create_autostash to run silently
Harald Nordgren [Tue, 28 Apr 2026 18:39:09 +0000 (18:39 +0000)] 
sequencer: allow create_autostash to run silently

Add a silent parameter to create_autostash_internal and introduce
create_autostash_ref_silent so that callers can create an autostash
without printing the "Created autostash" message.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agostash: add --label-ours, --label-theirs, --label-base for apply
Harald Nordgren [Tue, 28 Apr 2026 18:39:08 +0000 (18:39 +0000)] 
stash: add --label-ours, --label-theirs, --label-base for apply

Allow callers of "git stash apply" to pass custom labels for conflict
markers instead of the default "Updated upstream" and "Stashed changes".
Document the new options and add a test.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoindex-pack, unpack-objects: increase input buffer from 4 KiB to 128 KiB
Scott Bauersfeld [Tue, 28 Apr 2026 14:47:40 +0000 (14:47 +0000)] 
index-pack, unpack-objects: increase input buffer from 4 KiB to 128 KiB

index-pack and unpack-objects both read pack data from stdin through
a 4 KiB static buffer. In index-pack, each fill() flushes consumed
bytes to the pack file via write_or_die(), capping every write(2)
at 4 KiB. unpack-objects uses the same buffer pattern for reads.

On FUSE-backed filesystems every write(2) is a synchronous round
trip through the FUSE protocol (userspace -> kernel -> userspace ->
back), so the 4 KiB buffer turns a clone into many unnecessary tiny
writes with noticeable latency overhead.

Increase the buffer from 4 KiB to 128 KiB. Introduce a shared
DEFAULT_IO_BUFFER_SIZE constant in git-compat-util.h (next to
MAX_IO_SIZE) and use it in index-pack, unpack-objects, and the
hashfile layer in csum-file (which already used 128 KiB but
hardcoded the value).

Pack file writes to a FUSE filesystem with writeback caching
disabled during HTTPS clones of git/git (~293 MB pack):

  74,958 -> 4,687 (94% fewer)

Wall-clock time of git clone over HTTPS onto a FUSE passthrough
filesystem with writeback caching disabled, 3 runs per variant:

  vscode (~1.26 GB pack): 84.5s -> 75.7s avg (10% faster)
  git/git (~306 MB pack):  22.6s -> 20.0s avg (11% faster)

Signed-off-by: Scott Bauersfeld <sbauersfeld@g.ucla.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot5564: use a short path for the SOCKS proxy socket
Johannes Schindelin [Wed, 29 Apr 2026 08:22:54 +0000 (08:22 +0000)] 
t5564: use a short path for the SOCKS proxy socket

The SOCKS proxy test introduced in 0ca365c2ed4 (http: do not ignore
proxy path, 2024-08-02) creates a Unix domain socket in
`$TRASH_DIRECTORY`. When the trash directory path is long (e.g.
when running from a deeply nested worktree), the socket path can
exceed the 108-character limit for `struct sockaddr_un.sun_path` on
Linux, causing the test to fail with "Path length ... is longer
than maximum supported length (108)".

We cannot work around this using the chdir trick our own socket code
employs, because both sides of the connection are outside our control:
the socket is created by socks4-proxy.pl via Perl's IO::Socket::UNIX,
and the client side is libcurl.

Use `mktemp -d` to create a unique temporary directory with a short
path, and place the socket inside it. This avoids collisions between
concurrent test runs (e.g. `--stress`) and tmpdir-race vulnerabilities
that a static `/tmp` path would be susceptible to.

Helped-by: Jeff King <peff@peff.net>
Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot2000: consolidate second scenario into a single test block
Zakariyah Ali [Wed, 29 Apr 2026 10:36:06 +0000 (11:36 +0100)] 
t2000: consolidate second scenario into a single test block

The second test scenario in t2000 consists of several fragmented
test_expect_success blocks that handle data setup, tree writes,
execution of git-checkout-index, and final state validation.

Consolidate these nine separate blocks into a single self-contained
test block. This follows the modern Git testing standard where setup,
execution, and validation of a single logical scenario are kept
together.

As a result of this consolidation, the show_files() helper and its
associated test_debug calls are no longer used and have been removed.
This also removes a dependency on the non-portable 'find -ls' command.

Helped-by: Karthik Nayak <karthik.188@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Zakariyah Ali <zakariyahali100@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agocommit: sign commit after mutating buffer
brian m. carlson [Mon, 27 Apr 2026 22:18:34 +0000 (22:18 +0000)] 
commit: sign commit after mutating buffer

The ensure_utf8 function can mutate the buffer to change its encoding,
so we must call it before signing the buffer so that we do not
invalidate the signature, which is made over raw bytes.  Fix a bug which
caused the compatibility code to not convert the compatibility buffer if
the main buffer was invalid UTF-8.  We expect both buffers to be valid
UTF-8 or both invalid, since the only data that would differ between
them would be hex object IDs, which are always valid UTF-8.

Add a test for this case using 0xfe and 0xff, which are never valid in
UTF-8.

Reported-by: Kushal Das <kushal@sunet.se>
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agocommit: name UTF-8 function appropriately
brian m. carlson [Mon, 27 Apr 2026 22:18:33 +0000 (22:18 +0000)] 
commit: name UTF-8 function appropriately

We have a function named verify_utf8, but it does more than verify, it
modifies the buffer if it is not UTF-8.  This is different from what
most people would expect, so call the function ensure_utf8, since it
mutates the buffer in some cases.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agodoc: log: use the same delimiter in description list
Kristoffer Haugsbakk [Mon, 27 Apr 2026 19:06:50 +0000 (21:06 +0200)] 
doc: log: use the same delimiter in description list

We must use the same delimiter since this is a meant to be a flat
list. Introducing a new legal delimiter like `::` makes an inner
description list:

    ...
    full
    the full ref name ...

        auto
        if the output ...

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agodoc: log: fix --decorate description list
Kristoffer Haugsbakk [Mon, 27 Apr 2026 19:06:49 +0000 (21:06 +0200)] 
doc: log: fix --decorate description list

026f2e3b (doc: convert git-log to new documentation format, 2025-07-07)
transformed the inline description of `--decorate` options to a
description list:

    We also transform inline descriptions of possible values of option
    --decorate into a list, which is more readable and extensible.

But a source code block was used instead of an open block.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agobuiltin/history: introduce "fixup" subcommand
Patrick Steinhardt [Mon, 27 Apr 2026 05:53:53 +0000 (07:53 +0200)] 
builtin/history: introduce "fixup" subcommand

The newly introduced git-history(1) command provides functionality to
easily edit commit history while also rebasing dependent branches. The
functionality exposed by this command is still somewhat limited though.

One common use case when editing commit history that is not yet covered
is fixing up a specific commit. Introduce a new subcommand that allows
the user to do exactly that by performing a three-way merge into the
target's commit tree, using HEAD's tree as the merge base. The flow is
thus essentially:

    $ echo changes >file
    $ git add file
    $ git history fixup HEAD~

Like with the other commands, this will automatically rebase dependent
branches, as well. Unlike the other commands though:

  - The command does not work in a bare repository as it interacts with
    the index.

  - The command may run into merge conflicts. If so, the command will
    simply abort.

Especially the second item limits the usefulness of this command a bit.
But there are plans to introduce first-class conflicts into Git, which
will help use cases like this one.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agobuiltin/history: generalize function to commit trees
Patrick Steinhardt [Mon, 27 Apr 2026 05:53:52 +0000 (07:53 +0200)] 
builtin/history: generalize function to commit trees

The function `commit_tree_with_edited_message_ext()` can be used to
commit a tree with a specific list of parents with an edited commit
message. This function is useful outside of editing the commit message
though, as it also performs the plumbing to extract the original commit
message and strip some headers from it.

Refactor the function to receive a flags field that allows the caller to
control whether or not the commit message should be edited, or whether
it should be retained as-is. This will be used in a subsequent commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoreplay: allow callers to control what happens with empty commits
Patrick Steinhardt [Mon, 27 Apr 2026 05:53:51 +0000 (07:53 +0200)] 
replay: allow callers to control what happens with empty commits

When replaying commits it may happen that some of the commits become
empty relative to their parent. Such commits are for now automatically
dropped by the replay subsystem without much control from the user.

Introduce a new enum that allows the caller to drop, keep or abort in
this case.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agosafe.bareRepository: default to "explicit" with WITH_BREAKING_CHANGES
Johannes Schindelin [Sun, 26 Apr 2026 14:38:36 +0000 (14:38 +0000)] 
safe.bareRepository: default to "explicit" with WITH_BREAKING_CHANGES

When an attacker can convince a user to clone a crafted repository
that contains an embedded bare repository with malicious hooks, any Git
command the user runs after entering that subdirectory will discover
the bare repository and execute the hooks. The user does not even need
to run a Git command explicitly: many shell prompts run `git status`
in the background to display branch and dirty state information, and
`git status` in turn may invoke the fsmonitor hook if so configured,
making the user vulnerable the moment they `cd` into the directory. The
`safe.bareRepository` configuration variable (introduced in 8959555cee7e
(setup_git_directory(): add an owner check for the top-level directory,
2022-03-02)) already provides protection against this attack vector by
allowing users to set it to "explicit", but the default remained "all"
for backwards compatibility.

Since Git 3.0 is the natural point to change defaults to safer
values, flip the default from "all" to "explicit" when built with
`WITH_BREAKING_CHANGES`. This means Git will refuse to work with bare
repositories that are discovered implicitly by walking up the directory
tree. Bare repositories specified via `--git-dir` or `GIT_DIR` continue
to work, and directories that look like `.git`, worktrees, or submodule
directories are unaffected (the existing `is_implicit_bare_repo()`
whitelist handles those cases).

Users who rely on implicit bare repository discovery can restore the
previous behavior by setting `safe.bareRepository=all` in their global
or system configuration.

The test for the "safe.bareRepository in the repository" scenario
needed a more involved fix: it writes a `safe.bareRepository=all`
entry into the bare repository's own config to verify that repo-local
config does not override the protected (global) setting. Previously,
`test_config -C` was used to write that entry, but its cleanup runs `git
-C <bare-repo> config --unset`, which itself fails when the default is
"explicit" and the global config has already been cleaned up. Switching
to direct git config --file access avoids going through repository
discovery entirely.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agostatus tests: filter `.gitconfig` from status output
Johannes Schindelin [Sun, 26 Apr 2026 14:38:35 +0000 (14:38 +0000)] 
status tests: filter `.gitconfig` from status output

Since test-lib.sh creates `$HOME/.gitconfig` when
`WITH_BREAKING_CHANGES` is in effect, the file appears in `git
status` output as either untracked (`?? .gitconfig`) or ignored
(`!! .gitconfig` / `! .gitconfig`, depending on porcelain version),
because the `.git/info/exclude` entry causes git to treat it as an
ignored file rather than hiding it entirely.

In t7061 and t7521, which are pervasively affected, introduce a
`filter_gitconfig` helper that strips all status-prefix variants of
`.gitconfig` from the output before comparison. In the remaining
scripts (t7060, t7064, t7508), apply targeted adjustments.

Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agols-files tests: filter `.gitconfig` from `--others` output
Johannes Schindelin [Sun, 26 Apr 2026 14:38:34 +0000 (14:38 +0000)] 
ls-files tests: filter `.gitconfig` from `--others` output

The global `safe.bareRepository=all` setting in test-lib.sh is
written to `$HOME/.gitconfig`, which unfortunately lives inside the
test repository's working tree. The `.git/info/exclude` entry added
alongside it handles most commands, but `git ls-files --others`
without `--exclude-standard` does not consult `info/exclude` at
all, so the file appears in the output.

Ideally, each test that accesses a bare repository would simply
specify `--git-dir` or `GIT_DIR` explicitly, which would require no
global config and produce no side effects in the working tree. As
that approach was not taken, filter `.gitconfig` from the output
before comparing against expected results. In t7104, the test
already uses `--exclude-standard`, so it suffices to switch from
the bare `git ls-files -o` to `git ls-files -o --exclude-standard`
which respects the `info/exclude` entry; the other tests
deliberately omit `--exclude-standard` because their purpose is to
verify unfiltered `--others` output.

Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot5601: restore `.gitconfig` after includeIf test
Johannes Schindelin [Sun, 26 Apr 2026 14:38:33 +0000 (14:38 +0000)] 
t5601: restore `.gitconfig` after includeIf test

One test in t5601 overwrites `$HOME/.gitconfig` with an `includeIf`
configuration snippet and removes the file in its cleanup. This
destroys the `safe.bareRepository=all` entry that test-lib.sh
writes when `WITH_BREAKING_CHANGES` is in effect, causing later
tests that use `git -C <bare-repo> config` to fail with "not in a
git directory".

Back up `.gitconfig` before overwriting and restore it in the
cleanup, so the global config survives into subsequent tests.

Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot1305: use `--git-dir=.` for bare repo in include cycle test
Johannes Schindelin [Sun, 26 Apr 2026 14:38:32 +0000 (14:38 +0000)] 
t1305: use `--git-dir=.` for bare repo in include cycle test

Earlier tests in t1305 overwrite `$HOME/.gitconfig` with their own
content as part of testing config includes. This clobbers the
`safe.bareRepository=all` entry that test-lib.sh writes when
`WITH_BREAKING_CHANGES` is in effect, causing `git -C cycle config`
to fail with "not in a git directory" when it tries to access the
bare repository created by `git init --bare cycle`.

Use `--git-dir=.` to access the bare repo explicitly, avoiding the
dependency on global config for repository discovery.

Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot1300: remove global config settings injected by test-lib.sh
Johannes Schindelin [Sun, 26 Apr 2026 14:38:31 +0000 (14:38 +0000)] 
t1300: remove global config settings injected by test-lib.sh

Since test-lib.sh now writes `safe.bareRepository=all` to the global
config when `WITH_BREAKING_CHANGES` is in effect, that entry shows
up in `git config --list` output. Tests in t1300 that expect exact
config contents then fail because of this unexpected extra line.

Unlike the working-tree contamination fixed in the preceding
commits, this is not about the file's existence but about its
content leaking into test expectations. Since t1300 does not use
bare repositories, simply remove the injected setting in a
preparatory step.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Assisted-by: Claude Opus 4.6
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot7900: do not let `$HOME/.gitconfig` interfere with XDG tests
Johannes Schindelin [Sun, 26 Apr 2026 14:38:30 +0000 (14:38 +0000)] 
t7900: do not let `$HOME/.gitconfig` interfere with XDG tests

The XDG config tests for `git maintenance register/unregister`
create a fresh `$XDG_CONFIG_HOME/git/config` and expect git to use
that location. However, if `$HOME/.gitconfig` exists (which may
happen when test-lib.sh writes global config, e.g. to set
`safe.bareRepository`), git prefers `$HOME/.gitconfig` over the XDG
location, and the `maintenance.repo` entry ends up in the wrong
file.

This is an inherent consequence of setting global config in
test-lib.sh rather than adjusting individual tests: writing any
entry to `$HOME/.gitconfig` has side effects beyond the intended
setting, because the mere existence of that file changes which
global config location git prefers for all subsequent writes.
Individual per-test adjustments would not have this interaction.

Fix this by overriding `HOME` to a non-existent directory inside the
subshells that test XDG behavior. Since these subshells already
override `XDG_CONFIG_HOME`, they do not need `$HOME/.gitconfig` at
all, and the subshell scoping ensures the original `HOME` is
restored automatically.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agotest-lib: allow bare repository access when breaking changes are enabled
Johannes Schindelin [Sun, 26 Apr 2026 14:38:29 +0000 (14:38 +0000)] 
test-lib: allow bare repository access when breaking changes are enabled

A future patch will change the `safe.bareRepository` default from
`all` to `explicit` under `WITH_BREAKING_CHANGES`. At that point,
every test that operates on a bare repository through implicit
discovery would fail, regardless of whether the test is actually
about discovery or about how a specific command behaves once inside
a bare repository.

The maintainer suggested [1] setting `safe.bareRepository=all` in
the test environment's global config whenever `WITH_BREAKING_CHANGES`
is in effect, rather than adjusting each affected test to access
bare repositories explicitly (via `--git-dir`, `GIT_DIR`, or
similar). This means the test suite continues to exercise only the
historical default behavior even after the user-facing default
changes, relying on a small number of dedicated tests in t0035 to
validate the new, stricter default.

Since `$HOME` points at the trash directory (which doubles as the
test repository's working tree), writing to `$HOME/.gitconfig` also
creates a file inside the working tree. Exclude it via
`.git/info/exclude` to limit the fallout, though this does not
help tests that use `git ls-files --others` without
`--exclude-standard` or `git status --ignored`; those are addressed
by subsequent commits.

The `.git/info/exclude` write is guarded by `test -d .git/info`
rather than using `mkdir -p`, because some tests (e.g. t0008)
expect to create `.git/info/` themselves and would fail with
Patrick Steinhardt's `set -e` preparation (ps/test-set-e-clean) if
the directory already existed. For tests using `TEST_NO_CREATE_REPO`
(where no `.git/` exists at all), the guard also handles that case.

[1] https://lore.kernel.org/git/xmqqse98cc51.fsf@gitster.g/

Original-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agogrep: fix --column --only-match for 2nd and later matches
René Scharfe [Fri, 24 Apr 2026 21:04:27 +0000 (23:04 +0200)] 
grep: fix --column --only-match for 2nd and later matches

"git grep --column --only-match" shows the 1-based column number of the
first match on each line, but confusing numbers for further matches.
Example:

   $ echo 123456789012345678901234567890 >file
   $ for d in 1 2 3 4 5 6 7 8 9 0
     do
       git grep --no-index --column --only-matching $d file |
       awk -v FS=: -v l=$d: '{l = l sprintf("%3s", $2)} END {print l}'
     done
   1:  1  2 12
   2:  2  4 14
   3:  3  6 16
   4:  4  8 18
   5:  5 10 20
   6:  6 12 22
   7:  7 14 24
   8:  8 16 26
   9:  9 18 28
   0: 10 20 30

Report the column number of each match instead:

   $ for d in 1 2 3 4 5 6 7 8 9 0
     do
       ./git grep --no-index --column --only-matching $d file |
       awk -v FS=: -v l=$d: '{l = l sprintf("%3s", $2)} END {print l}'
     done
   1:  1 11 21
   2:  2 12 22
   3:  3 13 23
   4:  4 14 24
   5:  5 15 25
   6:  6 16 26
   7:  7 17 27
   8:  8 18 28
   9:  9 19 29
   0: 10 20 30

We need to adjust the test in t7810 as well.  The file it uses has the
following five lines; I add a line highlighting the matches and a ruler
at the bottom here, to make it easier to see that the second "mmap"
indeed starts at column 14:

foo mmap bar
foo_mmap bar
foo_mmap bar mmap
foo mmap bar_mmap
foo_mmap bar mmap baz
    ====     ====
123456789 123456789 1

Reported-by: Brandon Chinn <brandonchinn178@gmail.com>
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoalias: restore support for simple dotted aliases
Jonatan Holmgren [Fri, 24 Apr 2026 16:17:00 +0000 (18:17 +0200)] 
alias: restore support for simple dotted aliases

Historically, config entries like alias.foo.bar expanded the alias
"foo.bar". The subsection-based alias syntax introduced in
ac1f12a9de (alias: support non-alphanumeric names via subsection
syntax, 2026-02-18) broke that behavior by treating such entries as
if they were subsection syntax.

Restore support for the old dotted form by falling back to the full
name when the final key is not "command". Add tests covering execution
and help output for simple dotted aliases.

Reported-by: Michael Grossfeld <michael.grossfeld@amd.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Jonatan Holmgren <jonatan@jontes.page>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoRevert "transport-helper, connect: use clean_on_exit to reap children on abnormal...
Jeff King [Wed, 22 Apr 2026 23:00:20 +0000 (19:00 -0400)] 
Revert "transport-helper, connect: use clean_on_exit to reap children on abnormal exit"

This reverts commit dd3693eb0859274d62feac8047e1d486b3beaf31.

The goal of that commit was to avoid zombie child processes hanging
around when the parent git process is killed. But it doesn't quite work
when the child command is run by the shell:

  1. If there is a shell, then we kill and wait for the shell, not the
     process spawned by the shell. And so the child process, even if it
     eventually exits, will hang around as a zombie forever. And this is
     true of most (all?) shells: bash, dash, etc.

     So we are not really accomplishing our goal in the first place.

  2. Not all shells will exit immediately upon receiving a signal. In
     particular, mksh will wait for its children to exit (but not
     actually propagate the signal to them!) leaving us with a potential
     deadlock: git is wait()ing on mksh, which is wait()ing on a child
     process, but that child process is waiting on git to produce more
     input (or EOF) over a pipe.

     You can see several examples of this deadlock in the test suite,
     for example by running:

       make SHELL_PATH=/bin/mksh
       cd t
       ./t5702-protocol-v2.sh

Because this is a regression for mksh users, and because we did not
achieve our goal even with other shells, let's revert the commit for
now. If there is a more clever way of doing the same thing, we can
consider applying it separately on top (or do nothing and just accept
the zombies and rely on PID 1 to reap them).

Reported-by: Jan Palus <jpalus@fastmail.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot6112: avoid tilde expansion
SZEDER Gábor [Tue, 21 Apr 2026 19:21:32 +0000 (21:21 +0200)] 
t6112: avoid tilde expansion

e987df5fe6 (list-objects-filter: implement composite filters,
2019-06-27) introduced a test to "t6112-rev-list-filters-objects.sh"
that checks the output of a Git command with the following commands:

  grep ~$omitted_1 actual &&
  grep ~$omitted_2 actual &&
  grep ~$omitted_3 actual &&

Since the leading tilde in the pattern is not quoted/escaped, it is
subject to tilde expansion.  So if the system has a user whose
username happens to be "$omitted_1", then "grep" would look for that
user's home directory.

Quote those words starting with a tilde to avoid this.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agomerge-ort: handle cached rename & trivial resolution interaction better
Elijah Newren [Mon, 20 Apr 2026 22:30:14 +0000 (22:30 +0000)] 
merge-ort: handle cached rename & trivial resolution interaction better

Back in commit a562d90a350d (merge-ort: fix failing merges in special
corner case, 2025-11-03), we hit a rename assertion due to a trivial
directory resolution affecting the parent of a cached rename.  Since
the path didn't need to be considered, we side-stepped it with

   if (!newinfo)
     continue;

in process_renames().  We have since run into a case in production
where a trivial resolution of a file affects the direct target of a
cached rename rather than a parent directory of it.  Add a testcase
demonstrating this additional case.

Now, if we were to follow the lead of commit a562d90a350d, we could
resolve this alternate case with an extra condition on the above if:

   if (!newinfo || newinfo->merged.clean)
     continue;

However, if we had done that earlier, we would have made 979ee83e8a90
(merge-ort: fix corner case recursive submodule/directory conflict
handling, 2025-12-29) harder to find and fix, and this particular
position for this condition isn't actually at the root of the issue
but downstream from it.

Instead, let's rip out this if-check from a562d90a350d and put in an
alternative that more directly addresses trivially resolved paths that
happen to be cached renames or parent directories thereof, which is a
better fix for the original testcase and which also solves the newly
added testcase as well.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoFix docs for format.commitListFormat
Mirko Faina [Wed, 22 Apr 2026 21:45:17 +0000 (23:45 +0200)] 
Fix docs for format.commitListFormat

When renaming the option --cover-letter-format to --commit-list-format
we forgot to rename the opton in the section too. Fix it.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot: detect errors outside of test cases
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:25 +0000 (09:34 +0200)] 
t: detect errors outside of test cases

We have recently merged a patch series that had a simple misspelling of
`test_expect_success`. Instead of making our tests fail though, this
typo went completely undetected and all of our tests passed, which is of
course unfortunate. This is a more general issue with our test suite:
all commands that run outside of a specific test case can fail, and if
we don't explicitly check for such failure then this failure will be
silently ignored.

Improve the status quo by enabling the errexit option so that any such
unchecked failures will cause us to abort immediately.

Note that for now, we only enable this option for Bash 5 and newer. This
is because other shells have wildly different behaviour, and older
versions of Bash (especially on macOS) are buggy. The list of enabled
shells may be extended going forward.

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot9902: fix use of `read` with `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:24 +0000 (09:34 +0200)] 
t9902: fix use of `read` with `set -e`

In t9902 we're using the `read` builtin to read some values into a
variable. This is done by using `-d ""`, which cause us to read until
the end of the heredoc. As the read is terminated by EOF, the command
will end up returning a non-zero error code. This hasn't been an issue
until now as we didn't run with `set -e`, but that'll change in a
subsequent commit.

Prepare for this change by not using read at all, as we can simply store
the multi-line value directly.

Suggested-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot6002: fix use of `expr` with `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:23 +0000 (09:34 +0200)] 
t6002: fix use of `expr` with `set -e`

In `test_bisection_diff ()` we use `expr` to perform some math. This
command has some gotchas though in that it will only return success when
the result is neither null nor zero. In some of our cases though it
actually _is_ zero, and that will cause the expressions to fail once we
enable `set -e`.

Prepare for this change by instead using `$(( ))`, which doesn't have
the same issue. While at it, modernize the function a tiny bit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot1301: don't fail in case setfacl(1) doesn't exist or fails
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:22 +0000 (09:34 +0200)] 
t1301: don't fail in case setfacl(1) doesn't exist or fails

In t1301 we're trying to remove any potentially-existing default ACLs
that might exist on the transh directory by executing setfacl(1).
According to 8ed0a740dd (t1301-shared-repo.sh: don't let a default ACL
interfere with the test, 2008-10-16), this is done because we play
around with permissions and umasks in this test suite.

The setfacl(1) binary may not exist on some systems though, even though
tests ultimately still pass. This doesn't matter currently, but will
cause the test to fail once we start running with `set -e`. Silence such
failures by ignoring failures here.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot0008: silence error in subshell when using `grep -v`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:21 +0000 (09:34 +0200)] 
t0008: silence error in subshell when using `grep -v`

In t0008 we use `grep -v` in a subshell, but expect that this command
will sometimes not match anything. This would cause grep(1) to return an
error code, but given that we don't run with `set -e` we swallow this
error.

We're about to enable `set -e`. Prepare for this by ignoring any errors.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot: prepare `test_when_finished ()`/`test_atexit()` for `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:20 +0000 (09:34 +0200)] 
t: prepare `test_when_finished ()`/`test_atexit()` for `set -e`

Both `test_when_finished ()` and `test_atexit ()` build up a chain of
cleanup commands by prepending each new command to the existing cleanup
string. To preserve the exit code of the test body across cleanup
execution, we append the following logic:

    } && (exit "$eval_ret"); eval_ret=$?; ...

The intent of this is to run the cleanup block and then unconditionally
restore `eval_ret`. The original behaviour of this is is:

   +------------------+---------+------------------------------------+
   |test body         │ cleanup │ old behaviour                      │
   +------------------+---------+------------------------------------+
   │pass (eval_ret=0) | pass    │ && taken -> (exit 0) -> eval_ret=0 |
   +------------------+---------+------------------------------------+
   │pass (eval_ret=0) | fail    │ && not taken -> eval_ret=$?        |
   +------------------+---------+------------------------------------+
   │fail (eval_ret=1) | pass    │ && taken -> (exit 1) -> eval_ret=1 |
   +------------------+---------+------------------------------------+
   │fail (eval_ret=1) | fail    | && not taken -> eval_ret=$?        |
   +------------------+---------+------------------------------------+

This logic will start to fail once we enable `set -e`. When `$eval_ret`
is non-zero, the subshell we create will fail, and with `set -e` we'll
thus bail out without evaluating the logic after the semicolon.

Fix this issue by instead using `|| eval_ret=\$?; ...`. Besides being
a bit simpler, it also retains the original behaviour:

   +------------------+---------+------------------------------------+
   |test body         │ cleanup │ old behaviour                      │
   +------------------+---------+------------------------------------+
   │pass (eval_ret=0) | pass    │ || not taken -> eval_ret unchanged |
   +------------------+---------+------------------------------------+
   │pass (eval_ret=0) | fail    │ || taken -> eval_ret=$?            |
   +------------------+---------+------------------------------------+
   │fail (eval_ret=1) | pass    │ || not taken -> eval_ret unchanged |
   +------------------+---------+------------------------------------+
   │fail (eval_ret=1) | fail    | || taken -> eval_ret=$?            |
   +------------------+---------+------------------------------------+

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot: prepare execution of potentially failing commands for `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:19 +0000 (09:34 +0200)] 
t: prepare execution of potentially failing commands for `set -e`

Several of our tests verify whether a certain binary can be executed,
potentially skipping tests in case we cannot, for example because the
binary doesn't exist. In those cases we often run the binary outside of
any conditionally.

This will start to fail once we enable `set -e`, as that will cause us
to bail out the test immediately. Improve these tests by executing them
inside of a conditional instead.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot: prepare conditional test execution for `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:18 +0000 (09:34 +0200)] 
t: prepare conditional test execution for `set -e`

We have some test in our test suite where we use the pattern of
`test ... && test_expect_succeess` to conditionally execute a test. The
problem is that when we decide to not execute the test, we'll indeed
skip the test, but the overall statement will also be unsuccessful. This
will become a problem once we enable `set -e`.

Prepare for this future by turning this into a proper conditional, which
is also a bit easier to read overall.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot: prepare `git config --unset` calls for `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:17 +0000 (09:34 +0200)] 
t: prepare `git config --unset` calls for `set -e`

We have a couple of calls to `git config --unset` that ultimately end up
as no-ops as the configuration variables aren't set (anymore) in the
first place. These calls are mostly intended to recover unconditionally
from tests that may have executed only partially, but they'll ultimately
fail during a normal test run.

This hasn't been a problem until now as we aren't running tests with
`set -e`. This is about to change though, so let's silence the case
where we cannot unset the config keys.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot: prepare `stop_git_daemon ()` for `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:16 +0000 (09:34 +0200)] 
t: prepare `stop_git_daemon ()` for `set -e`

We have a couple of calls to `stop_git_daemon ()` outside of specific
test cases that will kill a backgrounded git-daemon(1) process and
expect the process with a specific error code. While these function
calls do end up killing git-daemon(1), the error handling we have in
those contexts is basically ineffective. So while we expect the process
to exit with a specific error code, we will just continue with any error
in case it doesn't.

This will change once we enable `set -e` in a subsequent commit. There's
two issues though that will make this _always_ fail:

  - Our call to `wait` is expected to fail, but because it's not part of
    a condition it will cause us to bail out immediately with `set -e`.

  - We try to kill git-daemon(1) a second time via the pidfile. We can
    generally expect that this is the same PID though as we had in the
    "GIT_DAEMON_PID" environment variable, and thus it's more likely
    than not that we have already killed it, and the call to kill will
    fail.

Prepare for this change by handling the failure of `wait` with `||` and
by silencing failures of the second call to `kill`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot: prepare `test_must_fail ()` for `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:15 +0000 (09:34 +0200)] 
t: prepare `test_must_fail ()` for `set -e`

The helper function `test_must_fail ()` executes a specific Git command
that may or may not fail in a specific way. This is done by executing
the command in question and then comparing its exit code against a set
of conditions.

This works, but once we run our test suite with `set -e` we may bail out
of `test_must_fail ()` early in case the command actually fails, even
though we expect it to fail. Prepare for this change by handling the
failed case with `||`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot: prepare `test_match_signal ()` calls for `set -e`
Patrick Steinhardt [Tue, 21 Apr 2026 07:34:14 +0000 (09:34 +0200)] 
t: prepare `test_match_signal ()` calls for `set -e`

We have a couple of calls to `test_match_signal ()` where we execute a
Git command and expect it to die with a specific signal. These calls
will essentially execute the process in a subshell via `foo; echo $?`,
but as we expect `foo` to fail this will cause the overall subshell to
fail once we `set -e`.

Fix this issue by using `foo && echo 0 || echo $?` instead.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot7004: avoid subshells to capture git exit codes
Siddharth Shrimali [Tue, 21 Apr 2026 05:33:34 +0000 (11:03 +0530)] 
t7004: avoid subshells to capture git exit codes

Several tests in t7004 use the 'test$(git ...) = ...' or the '! (git ...)'
subshell pattern. This swallows git's exit code. If git crashes
(e.g. segmentation fault) the crash would go undetected, and the test
would fail due to a mismatch or an inverted exit code.

Modernize these tests by directly writing output to files(actual) and
verifying them with 'test_cmp' or 'test_grep'. Replace subshell
negations with 'test_must_fail'. This way, if git crashes, the test
fails immediately and clearly instead of hiding the error behind a
string mismatch.

Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot7004: dynamically grab expected state in tests
Siddharth Shrimali [Tue, 21 Apr 2026 05:33:33 +0000 (11:03 +0530)] 
t7004: dynamically grab expected state in tests

The tests for 'Multiple -l or --list options' and 'trying to delete
tags without params', hardcodes that exactly one or two specific tags
('myhead', 'mytag') exist in the repository.

If other tests are added, modified, or removed earlier in the script,
this expected global state will change, resulting in these tests to fail
for completely unrelated reasons.

Instead of hardcoding the expected tags, dynamically grab the state
of the repository before running the commands under test ('git tag -l'
and 'git tag -d'), and verify that the output matches or remains
unchanged afterward. This keeps the tests independent from the script's
overall state.

Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agot7004: drop hardcoded tag count for state verification
Siddharth Shrimali [Tue, 21 Apr 2026 05:33:32 +0000 (11:03 +0530)] 
t7004: drop hardcoded tag count for state verification

The test 'trying to create a tag with a non-valid name should fail',
checked that exactly one tag existed in the repository before and after
attempting to create invalid tags.

As pointed out by Junio, this makes the test brittle by relying on a
specific global tag count. If future tests are added or removed before
this test, the expected state changes and this test would break for
completely unrelated reasons.

Modernize the test by taking a snapshot of the existing tags before the
failure attempts and comparing it to a snapshot taken after.
This provides a "belt-and-suspenders" approach: we verify that
'git tag' both exits with the expected error code and leaves the
repository state untouched, without being brittle to the specific
number of tags present.

This replaces the hardcoded 'test_line_count = 1' checks with 'test_cmp'
to ensure the tag list remains identical.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agodiff: fix out-of-bounds reads and NULL deref in diffstat UTF-8 truncation
Elijah Newren [Mon, 20 Apr 2026 15:42:58 +0000 (15:42 +0000)] 
diff: fix out-of-bounds reads and NULL deref in diffstat UTF-8 truncation

f85b49f3d4a (diff: improve scaling of filenames in diffstat to handle
UTF-8 chars, 2026-01-16) introduced a loop in show_stats() that calls
utf8_width() repeatedly to skip leading characters until the displayed
width fits.  However, utf8_width() can return problematic values:

  - For invalid UTF-8 sequences, pick_one_utf8_char() sets the name
    pointer to NULL and utf8_width() returns 0.  Since name_len does
    not change, the loop iterates once more and pick_one_utf8_char()
    dereferences the NULL pointer, crashing.

  - For control characters, utf8_width() returns -1, so name_len
    grows when it is expected to shrink.  This can cause the loop to
    consume more characters than the string contains, reading past
    the trailing NUL.

By default, fill_print_name() will C-quote filenames which escapes
control characters and invalid bytes to printable text.  That avoids
this bug from being triggered; however, with core.quotePath=false,
most characters are no longer escaped (though some control characters
still are) and raw bytes can reach this code.

Add tests exercising both failure modes with core.quotePath=false and
a narrow --stat-name-width to force truncation: one with a bare 0xC0
byte (invalid UTF-8 lead byte, triggers NULL deref) and one with
several C1 control characters (repeats of 0xC2 0x9F, causing
the loop to read past the end of the string).  The second test
reliably catches the out-of-bounds read when run under ASan, though
it may pass silently without sanitizers.

Fix both issues by introducing utf8_ish_width(), a thin wrapper
around utf8_width() that guarantees the pointer always advances and
the returned width is never negative:

  - On invalid UTF-8 it restores the pointer, advances by one byte,
    and returns width 1 (matching the strlen()-based fallback used
    by utf8_strwidth()).
  - On a control character it returns 0 (matching utf8_strnwidth()
    which skips them).

Also add a "&& *name" guard to the while-loop condition so it
terminates at end-of-string even when utf8_strwidth()'s strlen()
fallback causes name_len to exceed the sum of per-character widths.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoGit 2.54 v2.54.0
Junio C Hamano [Mon, 20 Apr 2026 02:01:39 +0000 (19:01 -0700)] 
Git 2.54

Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoMerge tag 'l10n-2.54.0-v2' of https://github.com/git-l10n/git-po
Junio C Hamano [Mon, 20 Apr 2026 01:59:09 +0000 (18:59 -0700)] 
Merge tag 'l10n-2.54.0-v2' of https://github.com/git-l10n/git-po

l10n-2.54.0-v2

* tag 'l10n-2.54.0-v2' of https://github.com/git-l10n/git-po:
  l10n: bg.po: Updated Bulgarian translation (6226t)
  l10n: zh_TW: update translation for Git 2.54
  l10n: Update Catalan Translation
  l10n: ga.po: update for Git 2.54
  l10n: fr: v2.54.0
  l10n: tr: Update Turkish translations
  l10n: sv.po: Update Swedish translation
  l10n: sv.po: correct various translations
  l10n: zh_CN: updated translation for 2.54
  l10n: bg.po: Updated Bulgarian translation (6226t)
  l10n: zh_CN: post-2.53 code review
  l10n: document AI and PO helper in po/README
  l10n: docs: add review instructions in AGENTS.md
  l10n: docs: add translation instructions in AGENTS.md
  l10n: docs: add update PO instructions in AGENTS.md
  l10n: docs: add AGENTS.md with update POT instructions
  l10n: add .gitattributes to simplify location filtering
  l10n: fix 'zh_TW.po' 'Applying patch'

6 weeks agoMerge branch 'master' of github.com:alshopov/git-po
Jiang Xin [Sun, 19 Apr 2026 23:37:21 +0000 (07:37 +0800)] 
Merge branch 'master' of github.com:alshopov/git-po

* 'master' of github.com:alshopov/git-po:
  l10n: bg.po: Updated Bulgarian translation (6226t)

6 weeks agol10n: bg.po: Updated Bulgarian translation (6226t)
Alexander Shopov [Sun, 19 Apr 2026 14:07:40 +0000 (16:07 +0200)] 
l10n: bg.po: Updated Bulgarian translation (6226t)

Improvements prompted by AI-assisted review

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
6 weeks agol10n: zh_TW: update translation for Git 2.54
Yi-Jyun Pan [Sun, 19 Apr 2026 13:52:38 +0000 (21:52 +0800)] 
l10n: zh_TW: update translation for Git 2.54

Signed-off-by: Yi-Jyun Pan <pan93412@gmail.com>
6 weeks agoMerge branch 'fr_v2.54.0' of github.com:jnavila/git
Jiang Xin [Sun, 19 Apr 2026 10:41:17 +0000 (18:41 +0800)] 
Merge branch 'fr_v2.54.0' of github.com:jnavila/git

* 'fr_v2.54.0' of github.com:jnavila/git:
  l10n: fr: v2.54.0

6 weeks agoMerge branch 'master' of github.com:alshopov/git-po
Jiang Xin [Sun, 19 Apr 2026 10:26:22 +0000 (18:26 +0800)] 
Merge branch 'master' of github.com:alshopov/git-po

* 'master' of github.com:alshopov/git-po:
  l10n: bg.po: Updated Bulgarian translation (6226t)

6 weeks agol10n: Update Catalan Translation
Mikel Forcada [Fri, 10 Apr 2026 19:55:34 +0000 (21:55 +0200)] 
l10n: Update Catalan Translation

Signed-off-by: Mikel Forcada <mikel.forcada@gmail.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
6 weeks agol10n: ga.po: update for Git 2.54
Aindriú Mac Giolla Eoin [Thu, 9 Apr 2026 14:50:17 +0000 (15:50 +0100)] 
l10n: ga.po: update for Git 2.54

Signed-off-by: Aindriú Mac Giolla Eoin <aindriu80@gmail.com>
6 weeks agoMerge branch 'master' of github.com:nafmo/git-l10n-sv
Jiang Xin [Sun, 19 Apr 2026 08:54:14 +0000 (16:54 +0800)] 
Merge branch 'master' of github.com:nafmo/git-l10n-sv

* 'master' of github.com:nafmo/git-l10n-sv:
  l10n: sv.po: Update Swedish translation
  l10n: sv.po: correct various translations

6 weeks agoMerge branch 'apply-patch-reject' of github.com:A4-Tacks/git-po
Jiang Xin [Sun, 19 Apr 2026 08:50:58 +0000 (16:50 +0800)] 
Merge branch 'apply-patch-reject' of github.com:A4-Tacks/git-po

* 'apply-patch-reject' of github.com:A4-Tacks/git-po:
  l10n: fix 'zh_TW.po' 'Applying patch'

7 weeks agoMerge branch 'tr-l10n' of github.com:bitigchi/git-po
Jiang Xin [Sun, 19 Apr 2026 03:13:45 +0000 (11:13 +0800)] 
Merge branch 'tr-l10n' of github.com:bitigchi/git-po

* 'tr-l10n' of github.com:bitigchi/git-po:
  l10n: tr: Update Turkish translations

7 weeks agoMerge branch 'zh_CN-2.54' of github.com:jiangxin/git
Jiang Xin [Sun, 19 Apr 2026 03:01:51 +0000 (11:01 +0800)] 
Merge branch 'zh_CN-2.54' of github.com:jiangxin/git

* 'zh_CN-2.54' of github.com:jiangxin/git:
  l10n: zh_CN: updated translation for 2.54

7 weeks agol10n: fr: v2.54.0
Jean-Noël Avila [Sat, 18 Apr 2026 04:05:05 +0000 (12:05 +0800)] 
l10n: fr: v2.54.0

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
7 weeks agoCodingGuidelines: st_mtimespec vs st_mtim vs st_mtime
Junio C Hamano [Fri, 10 Apr 2026 18:10:48 +0000 (11:10 -0700)] 
CodingGuidelines: st_mtimespec vs st_mtim vs st_mtime

Most unfortunately macOS does not support st_[amc]tim for timestamps
down to nanosecond resolution as POSIX systems.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agodoc: fix grammar errors in submodule description
Elijah Newren [Thu, 16 Apr 2026 23:36:31 +0000 (23:36 +0000)] 
doc: fix grammar errors in submodule description

6cc6d1b4c699 (Documentation: update add --force option + ignore=all
config, 2026-02-06) added text describing both the ignore=none and
ignore=all behaviors.  The former had minor formatting and grammatical
errors, while the latter was a bit garbled.  I have tried to tweak the
wording on the latter to make it read as I think was intended, and fixed
the minor grammatical issues with both as well.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agodoc: fix singular/plural mismatch in git-rerere
Elijah Newren [Thu, 16 Apr 2026 23:36:30 +0000 (23:36 +0000)] 
doc: fix singular/plural mismatch in git-rerere

conflict -> conflicts

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agodoc: fix plural agreement in pack.preferBitmapTips
Elijah Newren [Thu, 16 Apr 2026 23:36:29 +0000 (23:36 +0000)] 
doc: fix plural agreement in pack.preferBitmapTips

hierarchies -> hierarchy

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agodoc: fix self-referential config in sendemail.smtpSSLClientKey
Elijah Newren [Thu, 16 Apr 2026 23:36:28 +0000 (23:36 +0000)] 
doc: fix self-referential config in sendemail.smtpSSLClientKey

a8215a205141 (send-email: add client certificate options, 2026-03-02)
added documentation for sendemail.smtpSSLClientKey that says it works
"in conjunction with `sendemail.smtpSSLClientKey`" -- referring to
itself.  It appears that `sendemail.smtpSSLClientCert` was the intended
reference; fix it.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agoCodingGuidelines: fix subject-verb agreement
Elijah Newren [Thu, 16 Apr 2026 23:36:27 +0000 (23:36 +0000)] 
CodingGuidelines: fix subject-verb agreement

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agoRelNotes/2.54.0: fix typos and grammar
Elijah Newren [Thu, 16 Apr 2026 23:36:26 +0000 (23:36 +0000)] 
RelNotes/2.54.0: fix typos and grammar

Fix various issues in the release notes -- missing/wrong articles, typo,
indentation, quote consistency, and wording improvement or corrections.

Other than the indentation fix for "The way combined list-object filter
options...", this patch is much easier to view with --color-words.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agol10n: tr: Update Turkish translations
Emir SARI [Sat, 4 Apr 2026 19:09:05 +0000 (22:09 +0300)] 
l10n: tr: Update Turkish translations

Signed-off-by: Emir SARI <emir_sari@icloud.com>
7 weeks agoMerge branch 'jk/midx-write-v1-by-default'
Junio C Hamano [Thu, 16 Apr 2026 22:43:26 +0000 (15:43 -0700)] 
Merge branch 'jk/midx-write-v1-by-default'

As writing version 2 MIDX files by default breaks older versions of
Git and its reimplementations, use V2 only when necessary.

* jk/midx-write-v1-by-default:
  MIDX: revert the default version to v1

7 weeks agoMIDX: revert the default version to v1
Jeff King [Thu, 16 Apr 2026 20:06:59 +0000 (16:06 -0400)] 
MIDX: revert the default version to v1

We introduced midx version 2 in b2ec8e90c2 (midx: do not require packs
to be sorted in lexicographic order, 2026-02-24) and now write it by
default. The rationale was that older versions should ignore the v2 midx
and fall back to using the packs (just like we do for other midx
errors). Unfortunately this is not the case, as we have a hard die()
when we see an unknown midx version.

As a result, writing a midx with Git 2.54-rc2 puts the repository into a
state that is unusable with Git 2.53. And this midx write may happen
behind the scenes as part of normal operations, like fetch.

Let's switch back to writing v1 by default to avoid regressing the case
where multiple versions of Git are used on the same repository.

There is one gotcha, though: the v2 format is required for some new
features, like midx compaction, and running "git multi-pack-index
compact" will complain when asked to write a v1 index. The user must set
midx.version to "2" to make the feature work.

So instead of always using v1, we'll base the default on whether the
requested feature requires v2. That does mean that running midx
compaction will create a repository that can't be read by older versions
of Git. But we never do that by default; only people experimenting with
the new feature will be affected.

We have to adjust the test expectation in t5319, since it will now
generate v1 files. And our "auto-select v2" is covered by the tests in
t5335, which continue to check that compaction works without having to
set midx.version manually (and also explicitly check that asking for v1
with compaction reports the problem).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agot5563: add tests for http.emptyAuth with Negotiate
Matthew John Cheetham [Thu, 16 Apr 2026 09:20:59 +0000 (09:20 +0000)] 
t5563: add tests for http.emptyAuth with Negotiate

Add tests exercising the interaction between http.emptyAuth and
servers that advertise Negotiate (SPNEGO) authentication.

Verify that auto mode gives Negotiate a chance via empty auth
(resulting in two 401 responses before falling through to
credential_fill with Basic credentials), and that false mode
strips Negotiate immediately (only one 401 response).

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agohttp: attempt Negotiate auth in http.emptyAuth=auto mode
Matthew John Cheetham [Thu, 16 Apr 2026 09:20:58 +0000 (09:20 +0000)] 
http: attempt Negotiate auth in http.emptyAuth=auto mode

When a server advertises Negotiate (SPNEGO) authentication, the
"auto" mode of http.emptyAuth should detect this as an "exotic"
method and proactively send empty credentials, allowing libcurl to
use the system Kerberos ticket without prompting the user.

However, two features interact to prevent this from working:

The Negotiate-stripping logic, introduced in 4dbe66464b
(remote-curl: fall back to Basic auth if Negotiate fails,
2015-01-08), removes CURLAUTH_GSSNEGOTIATE from the allowed
methods on the first 401 response. The empty-auth auto-detection,
introduced in 40a18fc77c (http: add an "auto" mode for
http.emptyauth, 2017-02-25), then checks the remaining methods
for anything "exotic" -- but Negotiate has already been removed,
so auto mode never activates for servers whose only non-Basic/Digest
method is Negotiate (e.g., Apache with mod_auth_kerb offering
Basic + Negotiate).

Fix this by delaying the Negotiate stripping in auto mode: on the
first 401, keep Negotiate in the allowed methods so that auto mode
can detect it and retry with empty credentials. If that attempt
fails (no valid Kerberos ticket), strip Negotiate on the second 401
and fall through to credential_fill() as usual.

To support this, also teach http_reauth_prepare() to skip
credential_fill() when empty auth is about to be attempted, since
filling real credentials would bypass the empty-auth mechanism.

The true and false modes are unchanged: true sends empty credentials
on the very first request (before any 401), and false never sends
them.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agohttp: extract http_reauth_prepare() from retry paths
Matthew John Cheetham [Thu, 16 Apr 2026 09:20:57 +0000 (09:20 +0000)] 
http: extract http_reauth_prepare() from retry paths

All three HTTP retry paths (http_request_recoverable, post_rpc,
probe_rpc) call credential_fill() directly when handling
HTTP_REAUTH. Extract this into a helper function so that a
subsequent commit can add pre-fill logic (such as attempting
empty-auth before prompting) in one place.

No functional change.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agol10n: sv.po: Update Swedish translation
Peter Krefting [Thu, 16 Apr 2026 11:30:54 +0000 (12:30 +0100)] 
l10n: sv.po: Update Swedish translation

Signed-off-by: Peter Krefting <peter@softwolves.pp.se>
7 weeks agol10n: sv.po: correct various translations
Stefan Björnelund [Fri, 13 Feb 2026 20:14:23 +0000 (21:14 +0100)] 
l10n: sv.po: correct various translations

- correct translation of pathspec msgs
  Corrects cases where the “pathspec” is translated as if it was a
  path
- correct translation of refspec msgs
  Corrects cases where the “refspec” were not consistently translated
- correct translation of credential msgs
  Corrects cases where the “credential” were not correctly translated

Signed-off-by: Stefan Björnelund <stefan.bjornelund.gnome@gmail.com>
Modified-by: Peter Krefting <peter@softwolves.pp.se>
7 weeks agocat-file: add mailmap subcommand to --batch-command
Siddharth Asthana [Thu, 16 Apr 2026 03:32:50 +0000 (09:02 +0530)] 
cat-file: add mailmap subcommand to --batch-command

git-cat-file(1)'s --batch-command works with the --use-mailmap option,
but this option needs to be set when the process is created. This means
we cannot change this option mid-operation.

At GitLab, Gitaly keeps interacting with a long-lived git-cat-file
process and it would be useful if --batch-command supported toggling
mailmap dynamically on an existing process.

Add a `mailmap` subcommand to --batch-command that takes a boolean
argument (usual ways you can specify a boolean value like 'yes', 'true',
etc., are supported). Mailmap data is loaded lazily and kept in memory,
while a helper centralizes the one-time load path used both at startup
and from the batch-command handler.

Extend tests to cover runtime toggling, startup option interactions
(`--mailmap`/`--no-mailmap`), accepted boolean forms, and invalid values.

Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agol10n: zh_CN: updated translation for 2.54
Jiang Xin [Tue, 31 Mar 2026 02:17:35 +0000 (10:17 +0800)] 
l10n: zh_CN: updated translation for 2.54

Translate 198 previously fuzzy or untranslated messages, bringing the
total number of translated messages to 6226.

Reviewed-by: 依云 <lilydjwg@gmail.com>
Reviewed-by: Fangyi Zhou <me@fangyi.io>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
7 weeks agobackfill: default to grabbing edge blobs too
Elijah Newren [Wed, 15 Apr 2026 23:58:02 +0000 (23:58 +0000)] 
backfill: default to grabbing edge blobs too

Commit 302aff09223f (backfill: accept revision arguments, 2026-03-26) added
support for accepting revision arguments to backfill.  This allows users
to do things like

   git backfill --remotes ^v2.3.0

and then run many commands without triggering on-demand downloads of
blobs.  However, if they have topics based on v2.3.0, they will likely
still trigger on-demand downloads.  Consider, for example, the command

   git log -p v2.3.0..topic

This would still trigger on-demand blob loadings after the backfill
command above, because the commit(s) with A as a parent will need to
diff against the blobs in A.  In fact, multiple commands need blobs from
the lower boundary of the revision range:

   * git log -p A..B                # After backfill A..B
   * git replay --onto TARGET A..B  # After backfill TARGET^! A..B
   * git checkout A && git merge B  # After backfill A...B

Add an extra --[no-]include-edges flag to allow grabbing blobs from
edge commits.  Since the point of backfill is to prevent on-demand blob
loading and these are common commands, default to --include-edges.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agobackfill: document acceptance of revision-range in more standard manner
Elijah Newren [Wed, 15 Apr 2026 23:58:01 +0000 (23:58 +0000)] 
backfill: document acceptance of revision-range in more standard manner

302aff09223f (backfill: accept revision arguments, 2026-03-26) added
support for passing revision arguments to 'git backfill' but documented
them only with a prose sentence:

    You may also specify the commit limiting options from
    git-rev-list(1).

No other command that accepts revision arguments documents them this
way.  Commands like log, shortlog, and replay define a formal
<revision-range> entry and include rev-list-options.adoc.  Commands like
bundle, fast-export, and filter-branch, which pass arguments through to
the revision machinery without including the full options file, still
define a formal <git-rev-list-args> entry explaining what is accepted.

Add a formal <revision-range> entry in the synopsis and OPTIONS section,
following the convention used by other commands, and mention that
commit-limiting options from git-rev-list(1) are also accepted.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agobackfill: reject rev-list arguments that do not make sense
Elijah Newren [Wed, 15 Apr 2026 23:58:00 +0000 (23:58 +0000)] 
backfill: reject rev-list arguments that do not make sense

Some rev-list options accepted by setup_revisions() are silently
ignored or actively counterproductive when used with 'git backfill',
because the path-walk API has its own tree-walking logic that bypasses
the mechanisms these options rely on:

  * -S/-G (pickaxe) and --diff-filter work by computing per-commit
    diffs in get_revision_1() and filtering commits whose diffs don't
    match.  Since backfill's goal is to download all blobs reachable
    from commits in the range, filtering out commits based on diff
    content would silently skip blobs -- the opposite of what users
    want.

  * --follow disables path pruning (revs->prune) and only makes
    sense for tracking a single file through renames in log output.
    It has no useful interaction with backfill.

  * -L (line-log) computes line-level diffs to track the evolution
    of a function or line range.  Like pickaxe, it filters commits
    based on diff content, which would cause blobs to be silently
    skipped.

  * --diff-merges controls how merge commit diffs are displayed.
    The path-walk API walks trees directly and never computes
    per-commit diffs, so this option would be silently ignored.

  * --filter (object filtering, e.g. --filter=blob:none) is used by
    the list-objects traversal but is completely ignored by the
    path-walk API, so it would silently do nothing.

Rather than letting users think these options are being honored,
reject them with a clear error message.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agocodeql: bump actions/cache from 4 to 5
Johannes Schindelin [Mon, 13 Apr 2026 16:24:17 +0000 (16:24 +0000)] 
codeql: bump actions/cache from 4 to 5

Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major

Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agol10n: bg.po: Updated Bulgarian translation (6226t)
Alexander Shopov [Tue, 7 Apr 2026 07:32:08 +0000 (09:32 +0200)] 
l10n: bg.po: Updated Bulgarian translation (6226t)

Signed-off-by: Alexander Shopov <ash@kambanaria.org>