]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
2 months agoMerge branch 'qb/doc-git-stash-push-optionality'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'qb/doc-git-stash-push-optionality'

Doc update.

* qb/doc-git-stash-push-optionality:
  docs: fix "git stash [push]" documentation

2 months agoMerge branch 'sp/doc-gitignore-oowt'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'sp/doc-gitignore-oowt'

Doc update.

* sp/doc-gitignore-oowt:
  doc: gitignore: clarify pattern base for info/exclude and core.excludesFile

2 months agoMerge branch 'th/t6101-unhide-git-failures'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'th/t6101-unhide-git-failures'

Test cleanup.

* th/t6101-unhide-git-failures:
  t6101: avoid suppressing git's exit code

2 months agoMerge branch 'za/t2000-modernise'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'za/t2000-modernise'

Test cleanup.

* za/t2000-modernise:
  t2000: modernise overall structure

2 months agoMerge branch 'tc/replay-down-to-root'
Junio C Hamano [Mon, 6 Apr 2026 22:42:49 +0000 (15:42 -0700)] 
Merge branch 'tc/replay-down-to-root'

git replay now supports replaying down to the root commit.

* tc/replay-down-to-root:
  replay: support replaying down from root commit

2 months agoMerge branch 'tb/stdin-packs-excluded-but-open'
Junio C Hamano [Mon, 6 Apr 2026 22:42:49 +0000 (15:42 -0700)] 
Merge branch 'tb/stdin-packs-excluded-but-open'

pack-objects's --stdin-packs=follow mode learns to handle
excluded-but-open packs.

* tb/stdin-packs-excluded-but-open:
  repack: mark non-MIDX packs above the split as excluded-open
  pack-objects: support excluded-open packs with --stdin-packs
  t7704: demonstrate failure with once-cruft objects above the geometric split
  pack-objects: refactor `read_packs_list_from_stdin()` to use `strmap`
  pack-objects: plug leak in `read_stdin_packs()`

2 months agoMerge branch 'ps/odb-generic-object-name-handling'
Junio C Hamano [Mon, 6 Apr 2026 22:42:48 +0000 (15:42 -0700)] 
Merge branch 'ps/odb-generic-object-name-handling'

Object name handling (disambiguation and abbreviation) has been
refactored to be backend-generic, moving logic into the respective
object database backends.

* ps/odb-generic-object-name-handling:
  odb: introduce generic `odb_find_abbrev_len()`
  object-file: move logic to compute packed abbreviation length
  object-name: move logic to compute loose abbreviation length
  object-name: simplify computing common prefixes
  object-name: abbreviate loose object names without `disambiguate_state`
  object-name: merge `update_candidates()` and `match_prefix()`
  object-name: backend-generic `get_short_oid()`
  object-name: backend-generic `repo_collect_ambiguous()`
  object-name: extract function to parse object ID prefixes
  object-name: move logic to iterate through packed prefixed objects
  object-name: move logic to iterate through loose prefixed objects
  odb: introduce `struct odb_for_each_object_options`
  oidtree: extend iteration to allow for arbitrary return codes
  oidtree: modernize the code a bit
  object-file: fix sparse 'plain integer as NULL pointer' error

2 months agocache-tree: fix inverted object existence check in cache_tree_fully_valid
David Lin [Mon, 6 Apr 2026 19:27:11 +0000 (15:27 -0400)] 
cache-tree: fix inverted object existence check in cache_tree_fully_valid

The negation in front of the object existence check in
cache_tree_fully_valid() was lost in 062b914c84 (treewide: convert
users of `repo_has_object_file()` to `has_object()`, 2025-04-29),
turning `!repo_has_object_file(...)` into `has_object(...)` instead
of `!has_object(...)`.

This makes cache_tree_fully_valid() always report the cache tree as
invalid when objects exist (the common case), forcing callers like
write_index_as_tree() to call cache_tree_update() on every
invocation.  An odb_has_object() check inside update_one() avoids a
full tree rebuild, but the unnecessary call still pays the cost of
opening an ODB transaction and, in partial clones, a promisor remote
check.

Restore the missing negation and add a test that verifies write-tree
takes the cache-tree shortcut when the cache tree is valid.

Helped-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: David Lin <davidlin@stripe.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorev-list: use reduce_heads() for --maximal-only
Derrick Stolee [Mon, 6 Apr 2026 13:27:28 +0000 (13:27 +0000)] 
rev-list: use reduce_heads() for --maximal-only

The 'git rev-list --maximal-only' option filters the output to only
independent commits. A commit is independent if it is not reachable from
other listed commits. Currently this is implemented by doing a full
revision walk and marking parents with CHILD_VISITED to skip non-maximal
commits.

The 'git merge-base --independent' command computes the same result
using reduce_heads(), which uses the more efficient remove_redundant()
algorithm. This is significantly faster because it avoids walking the
entire commit graph.

Add a fast path in rev-list that detects when --maximal-only is the only
interesting option and all input commits are positive (no revision
ranges). In this case, use reduce_heads() directly instead of doing a
full revision walk.

In order to preserve the rest of the output filtering, this computation
is done opportunistically in a new prepare_maximal_independent() method
when possible. If successful, it populates revs->commits with the list
of independent commits and set revs->no_walk to prevent any other walk
from occurring. This allows us to have any custom output be handled
using the existing output code hidden inside
traverse_commit_list_filtered(). A new test is added to demonstrate that
this output is preserved.

The fast path is only used when no other flags complicate the walk or
output format: no UNINTERESTING commits, no limiting options (max-count,
age filters, path filters, grep filters), no output formatting beyond
plain OIDs, and no object listing flags.

Running the p6011 performance test for my copy of git.git, I see the
following improvement with this change:

  Test                                     HEAD~1  HEAD
  ------------------------------------------------------------
  6011.2: merge-base --independent          0.03   0.03 +0.0%
  6011.3: rev-list --maximal-only           0.06   0.03 -50.0%
  6011.4: rev-list --maximal-only --since   0.06   0.06 +0.0%

And for a fresh clone of the Linux kernel repository, I see:

  Test                                     HEAD~1  HEAD
  ------------------------------------------------------------
  6011.2: merge-base --independent          0.00   0.00 =
  6011.3: rev-list --maximal-only           0.70   0.00 -100.0%
  6011.4: rev-list --maximal-only --since   0.70   0.70 +0.0%

In both cases, the performance is indeed matching the behavior of 'git
merge-base --independent', as expected.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agop6011: add perf test for rev-list --maximal-only
Derrick Stolee [Mon, 6 Apr 2026 13:27:27 +0000 (13:27 +0000)] 
p6011: add perf test for rev-list --maximal-only

Add a performance test that compares 'git rev-list --maximal-only'
against 'git merge-base --independent'. These two commands are asking
essentially the same thing, but the rev-list implementation is more
generic and hence slower. These performance tests will demonstrate that
in the current state and also be used to show the equivalence in the
future.

We also add a case with '--since' to force the generic walk logic for
rev-list even when we make that future change to use the merge-base
algorithm on a simple walk.

When run on my copy of git.git, I see these results:

  Test                                      HEAD
  ----------------------------------------------
  6011.2: merge-base --independent          0.03
  6011.3: rev-list --maximal-only           0.06
  6011.4: rev-list --maximal-only --since   0.06

These numbers are low, but the --independent calculation is interesting
due to having a lot of local branches that are actually independent.

Running the same test on a fresh clone of the Linux kernel repository
shows a larger difference between the algorithms, especially because the
--independent algorithm is extremely fast when there are no independent
references selected:

  Test                                      HEAD
  ----------------------------------------------
  6011.2: merge-base --independent          0.00
  6011.3: rev-list --maximal-only           0.70
  6011.4: rev-list --maximal-only --since   0.70

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot6600: test --maximal-only and --independent
Derrick Stolee [Mon, 6 Apr 2026 13:27:26 +0000 (13:27 +0000)] 
t6600: test --maximal-only and --independent

Add a test that verifies the 'git rev-list --maximal-only' option
produces the same set of commits as 'git merge-base --independent'. This
equivalence was noted when the feature was first created, but we are
about to update the implementation to use a common algorithm in this
case where the user intention is identical.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohistory: fix short help for argument of --update-refs
René Scharfe [Mon, 6 Apr 2026 09:31:21 +0000 (11:31 +0200)] 
history: fix short help for argument of --update-refs

"print" is not a valid argument for --update-refs.  List both valid
alternatives literally in the argh string, consistent with documentation
and usage string.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agocompat/winansi: drop pre-Vista workaround
Matthias Aßhauer [Mon, 6 Apr 2026 05:45:30 +0000 (05:45 +0000)] 
compat/winansi: drop pre-Vista workaround

1edeb9a (Win32: warn if the console font doesn't support Unicode,
2014-06-10) introduced both code to detect the current console font on
Windows Vista and newer and a fallback for older systems to detect the
default console font and issue a warning if that font doesn't support
unicode.

Since we haven't supported any Windows older than Vista in almost a
decade, we don't need to keep the workaround.

Signed-off-by: Matthias Aßhauer <mha1993@live.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agounify and bump _WIN32_WINNT definition to Windows 8.1
Matthias Aßhauer [Mon, 6 Apr 2026 05:45:29 +0000 (05:45 +0000)] 
unify and bump _WIN32_WINNT definition to Windows 8.1

Git for Windows doesn't support anything prior to Windows 8.1 since 2.47.0
and Git followed along with commits like ce6ccba (mingw: drop Windows
7-specific work-around, 2025-08-04).

There is no need to pretend to the compiler that we still support Windows
Vista, just to lock us out of easy access to newer APIs. There is also no
need to have conflicting and unused definitions claiming we support some
versions of Windows XP or even Windows NT 4.0.

Bump all definitions of _WIN32_WINNT to a realistic value of Windows 8.1.
This will also simplify code for a followup commit that will improve cpu
core detection on multi-socket systems.

Signed-off-by: Matthias Aßhauer <mha1993@live.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodoc: gitcvs-migration: rephrase “man page”
Kristoffer Haugsbakk [Sun, 5 Apr 2026 10:32:00 +0000 (12:32 +0200)] 
doc: gitcvs-migration: rephrase “man page”

Let’s change the phrasing around the `linkgit` while we’re visiting this
file (see previous commit[1]).

We use the section syntax to refer to man pages, so writing “man page”
next to it is a bit redundant. We can be more concise and just lean on
the preposition “in”.

And in order to avoid this double “git”:

    see `git config list` in git-config(1) ...

We can rephrase to the subcommand, which is a typical pattern (config or
option followed by “in git-command(1)”).

† 1: Which also discusses why we do not change a similar phrasing
     in gittutorial(7)

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodoc: replace git config --list/-l with `list`
Kristoffer Haugsbakk [Sun, 5 Apr 2026 10:31:59 +0000 (12:31 +0200)] 
doc: replace git config --list/-l with `list`

Replace uses of `git config --list` (short or long) with the subcommand
`list` since `--list` is deprecated.

We will change the “man page” phrasing in gitcvs-migration(7) in the
next commit, since we are already visiting that sentence. But note
that we leave the “man page” phrasing in the sentence that we touch in
gittutorial(7) since it’s a tutorial and not a manual page. We can be
more wordy in a tutorial context.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodoc: convert git-describe manual page to synopsis style
Jean-Noël Avila [Sat, 4 Apr 2026 17:12:47 +0000 (17:12 +0000)] 
doc: convert git-describe manual page to synopsis style

     * convert commands and options to synopsis style
     * use _<placeholder>_ for arguments

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodoc: convert git-shortlog manual page to synopsis style
Jean-Noël Avila [Sat, 4 Apr 2026 17:12:46 +0000 (17:12 +0000)] 
doc: convert git-shortlog manual page to synopsis style

     * convert commands and options to synopsis style
     * use _<placeholder>_ for arguments
     * small style fixes

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodoc: convert git-range-diff manual page to synopsis style
Jean-Noël Avila [Sat, 4 Apr 2026 17:12:45 +0000 (17:12 +0000)] 
doc: convert git-range-diff manual page to synopsis style

     * convert commands and options to synopsis style
     * use _<placeholder>_ for arguments
     * small style fixes

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodoc: convert git-difftool manual page to synopsis style
Jean-Noël Avila [Sat, 4 Apr 2026 17:12:44 +0000 (17:12 +0000)] 
doc: convert git-difftool manual page to synopsis style

     * convert commands to synopsis style
     * use _<placeholder>_ for arguments
     * fix conditional text to sentence limits

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agobackfill: auto-detect sparse-checkout from config
Trieu Huynh [Sat, 4 Apr 2026 11:15:57 +0000 (18:15 +0700)] 
backfill: auto-detect sparse-checkout from config

Commit 85127bcdea ("backfill: assume --sparse when sparse-checkout is
enabled") intended for 'git backfill' to consult the repository
configuration when the user does not pass '--sparse' or
'--no-sparse' on the command line. It added the sentinel check:

    if (ctx->sparse < 0)
        ctx->sparse = cfg->apply_sparse_checkout;

However, the ctx->sparse field is initialized to 0 instead of -1,
so this guard never triggers. Consequently, the repository config
(core.sparseCheckout) is never checked, and the command always
performs a full backfill even when sparse-checkout is enabled.

Fix this by initializing ctx->sparse to -1, ensuring the existing
fallback logic correctly reads the repository configuration when
no explicit flags are provided.

Add a test to verify that 'git backfill' automatically respects
sparse-checkout settings when no flags are passed.

Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agogit-compat-util: fix CONST_OUTPARAM typo and indentation
Jeff King [Sat, 4 Apr 2026 05:42:11 +0000 (01:42 -0400)] 
git-compat-util: fix CONST_OUTPARAM typo and indentation

There's a typo in the comment, making it hard to understand. And the
macro itself is indented with spaces rather than tab.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'master' of https://github.com/git/git
Jiang Xin [Sat, 4 Apr 2026 03:53:49 +0000 (11:53 +0800)] 
Merge branch 'master' of https://github.com/git/git

Upstream adds 18 new translatable messages.

* 'master' of https://github.com/git/git: (41 commits)
  A bit more on top of 2.54-rc0
  ...

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agoA couple more on top of -rc0
Junio C Hamano [Fri, 3 Apr 2026 22:26:34 +0000 (15:26 -0700)] 
A couple more on top of -rc0

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'ps/dash-buggy-0.5.13-workaround'
Junio C Hamano [Fri, 3 Apr 2026 22:24:45 +0000 (15:24 -0700)] 
Merge branch 'ps/dash-buggy-0.5.13-workaround'

The way dash 0.5.13 handles non-ASCII contents in here-doc
is buggy and breaks our existing tests, which unfortunately
have been rewritten to avoid triggering the bug.

* ps/dash-buggy-0.5.13-workaround:
  t9300: work around partial read bug in Dash v0.5.13
  t: work around multibyte bug in quoted heredocs with Dash v0.5.13

2 months agoMerge branch 'js/cmake-needs-writev-compat-too'
Junio C Hamano [Fri, 3 Apr 2026 22:24:45 +0000 (15:24 -0700)] 
Merge branch 'js/cmake-needs-writev-compat-too'

Build instruction for recently added writev() compatibility wrapper
has been also added to cmake.

* js/cmake-needs-writev-compat-too:
  cmake: use writev(3p) wrapper as needed

2 months agoMerge branch 'js/mingw-use-strftime-directly-in-ucrt-build'
Junio C Hamano [Fri, 3 Apr 2026 22:24:44 +0000 (15:24 -0700)] 
Merge branch 'js/mingw-use-strftime-directly-in-ucrt-build'

MinGW build updates.

* js/mingw-use-strftime-directly-in-ucrt-build:
  mingw: use strftime() directly in UCRT builds

2 months agoA bit more on top of 2.54-rc0
Junio C Hamano [Fri, 3 Apr 2026 20:00:49 +0000 (13:00 -0700)] 
A bit more on top of 2.54-rc0

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'th/t8003-unhide-git-failures'
Junio C Hamano [Fri, 3 Apr 2026 20:01:09 +0000 (13:01 -0700)] 
Merge branch 'th/t8003-unhide-git-failures'

Test clean-up.

* th/t8003-unhide-git-failures:
  t8003: modernise style
  t8003: avoid suppressing git's exit code

2 months agoMerge branch 'sa/replay-revert'
Junio C Hamano [Fri, 3 Apr 2026 20:01:09 +0000 (13:01 -0700)] 
Merge branch 'sa/replay-revert'

"git replay" (experimental) learns, in addition to "pick" and
"replay", a new operating mode "revert".

* sa/replay-revert:
  replay: add --revert mode to reverse commit changes
  sequencer: extract revert message formatting into shared function

2 months agoMerge branch 'pw/worktree-reduce-the-repository'
Junio C Hamano [Fri, 3 Apr 2026 20:01:09 +0000 (13:01 -0700)] 
Merge branch 'pw/worktree-reduce-the-repository'

Reduce the reference to the_repository in the worktree subsystem.

* pw/worktree-reduce-the-repository:
  worktree: reject NULL worktree in get_worktree_git_dir()
  worktree add: stop reading ".git/HEAD"
  worktree: remove "the_repository" from is_current_worktree()

2 months agoMerge branch 'ar/config-hook-cleanups'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'ar/config-hook-cleanups'

Code clean-up around the recent "hooks defined in config" topic.

* ar/config-hook-cleanups:
  hook: reject unknown hook names in git-hook(1)
  hook: show disabled hooks in "git hook list"
  hook: show config scope in git hook list
  hook: introduce hook_config_cache_entry for per-hook data
  t1800: add test to verify hook execution ordering
  hook: make consistent use of friendly-name in docs
  hook: replace hook_list_clear() -> string_list_clear_func()
  hook: detect & emit two more bugs
  hook: rename cb_data_free/alloc -> hook_data_free/alloc
  hook: fix minor style issues
  builtin/receive-pack: properly init receive_hook strbuf
  hook: move unsorted_string_list_remove() to string-list.[ch]

2 months agoMerge branch 'ds/backfill-revs'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'ds/backfill-revs'

`git backfill` learned to accept revision and pathspec arguments.

* ds/backfill-revs:
  t5620: test backfill's unknown argument handling
  path-walk: support wildcard pathspecs for blob filtering
  backfill: work with prefix pathspecs
  backfill: accept revision arguments
  t5620: prepare branched repo for revision tests
  revision: include object-name.h

2 months agoMerge branch 'mf/format-patch-commit-list-format-doc'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'mf/format-patch-commit-list-format-doc'

Doc updates.

* mf/format-patch-commit-list-format-doc:
  format-patch: removing unconditional wrapping
  docs: fix --commit-list-format related entries

2 months agoMerge branch 'mf/format-patch-commit-list-format'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'mf/format-patch-commit-list-format'

Improve the recently introduced `git format-patch
--commit-list-format` (formerly `--cover-letter-format`) option,
including a new "modern" preset and better CLI ergonomics.

* mf/format-patch-commit-list-format:
  format-patch: --commit-list-format without prefix
  format-patch: add preset for --commit-list-format
  format-patch: wrap generate_commit_list_cover()
  format.commitListFormat: strip meaning from empty
  docs/pretty-formats: add %(count) and %(total)
  format-patch: rename --cover-letter-format option
  format-patch: refactor generate_commit_list_cover
  pretty.c: better die message %(count) and %(total)

2 months agoMerge branch 'mf/format-patch-cover-letter-format'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'mf/format-patch-cover-letter-format'

"git format-patch --cover-letter" learns to use a simpler format
instead of the traditional shortlog format to list its commits with
a new --cover-letter-format option and format.commitListFormat
configuration variable.

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

2 months agomingw: use strftime() directly in UCRT builds
Johannes Schindelin [Fri, 3 Apr 2026 09:56:23 +0000 (09:56 +0000)] 
mingw: use strftime() directly in UCRT builds

The `mingw_strftime()` wrapper exists to work around msvcrt.dll's
incomplete `strftime()` implementation by dynamically loading the
version from ucrtbase.dll at runtime via `LoadLibrary()` +
`GetProcAddress()`. When the binary is already linked against UCRT
(i.e. when building in the UCRT64 environment), the linked-in
`strftime()` is the ucrtbase.dll version, making the dynamic loading
needless churn: It's calling the very same code.

Simply guard both the declaration and implementation so that the
unnecessary work-around is skipped in UCRT builds.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agocmake: use writev(3p) wrapper as needed
Johannes Schindelin [Fri, 3 Apr 2026 08:55:02 +0000 (08:55 +0000)] 
cmake: use writev(3p) wrapper as needed

This is a companion patch of 3b9b2c2a29a (compat/posix: introduce
writev(3p) wrapper, 2026-03-13) where support for using the `writev()`
wrapper was introduced in the `Makefile` and the Meson-based build, but
the CMake build still needs that treatment, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agol10n: document AI and PO helper in po/README
Jiang Xin [Fri, 3 Apr 2026 06:40:01 +0000 (14:40 +0800)] 
l10n: document AI and PO helper in po/README

Document po/AGENTS.md-driven AI workflows (with an example prompt)
before the PO helper section, cross-reference git-po-helper, and
summarize quality checks plus optional agent integration in the PO
helper section.

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agol10n: docs: add review instructions in AGENTS.md
Jiang Xin [Wed, 25 Feb 2026 06:19:25 +0000 (14:19 +0800)] 
l10n: docs: add review instructions in AGENTS.md

Add a new "Reviewing po/XX.po" section to po/AGENTS.md that provides
comprehensive guidance for AI agents to review translation files.

Translation diffs lose context, especially for multi-line msgid and
msgstr entries. Some LLMs ignore context and cannot evaluate
translations accurately; others rely on scripts to search for context
in source files, making the review process time-consuming. To address
this, git-po-helper implements the compare subcommand, which extracts
new or modified translations with full context (complete msgid/msgstr
pairs), significantly improving review efficiency.

A limitation is that the extracted content lacks other
already-translated content for reference, which may affect terminology
consistency. This is mitigated by including a glossary in the PO file
header. git-po-helper-generated review files include the header entry
and glossary (if present) by default.

The review workflow leverages git-po-helper subcommands:

- git-po-helper compare: Extract new or changed entries between two
  versions of a PO file into a valid PO file for review. Supports
  multiple modes:

  * Compare HEAD with the working tree (local changes)
  * Compare a commit's parent with the commit (--commit)
  * Compare a commit with the working tree (--since)
  * Compare two arbitrary revisions (-r)

- git-po-helper msg-select: Split large review files into smaller
  batches by entry index range for manageable review sessions. Supports
  range formats like "-50" (first 50), "51-100", "101-" (to end).

Evaluation with the Qwen model:

    git-po-helper agent-run review --commit 2000abefba --agent qwen

Benchmark results:

    | Metric           | Value                            |
    |------------------|----------------------------------|
    | Turns            | 22                               |
    | Input tokens     | 537263                           |
    | Output tokens    | 4397                             |
    | API duration     | 167.84 s                         |
    | Review score     | 96/100                           |
    | Total entries    | 63                               |
    | With issues      | 4 (1 critical, 2 major, 1 minor) |

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agol10n: docs: add translation instructions in AGENTS.md
Jiang Xin [Sun, 15 Feb 2026 06:06:19 +0000 (14:06 +0800)] 
l10n: docs: add translation instructions in AGENTS.md

Add a new "Translating po/XX.po" section to po/AGENTS.md with detailed
workflow and procedures for AI agents to translate language-specific PO
files. Users can invoke AI-assisted translation in coding tools with a
prompt such as:

    "Translate the po/XX.po file by referring to @po/AGENTS.md"

Translation results serve as drafts; human contributors must review and
approve before submission.

To address the low translation efficiency of some LLMs, batch
translation replaces entry-by-entry translation. git-po-helper
implements a gettext JSON format for translation files, replacing PO
format during translation to enable batch processing.

Evaluation with the Qwen model:

    git-po-helper agent-run --agent=qwen translate po/zh_CN.po

Test translation (127 entries, 50 per batch):

    Initial state:  5998 translated, 91 fuzzy, 36 untranslated
    Final state:    6125 translated, 0 fuzzy, 0 untranslated

    Successfully translated: 127 entries (91 fuzzy + 36 untranslated)
    Success rate: 100%

Benchmark results (3-run average):

AI agent using gettext tools:

    | Metric           | Value                          |
    |------------------|--------------------------------|
    | Avg. Num turns   | 86 (176, 44, 40)               |
    | Avg. Exec. Time  | 20m44s (39m56s, 14m38s, 7m38s) |
    | Successful runs  | 3/3                            |

AI agent using git-po-helper (JSON batch flow):

    | Metric           | Value                          |
    |------------------|--------------------------------|
    | Avg. Num turns   | 56 (68, 39, 63)                |
    | Avg. Exec. Time  | 19m8s (28m55s, 9m1s, 19m28s)   |
    | Successful runs  | 3/3                            |

The git-po-helper flow reduces the number of turns (86 → 56) with
similar execution time; the bottleneck appears to be LLM processing
rather than network interaction.

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agol10n: docs: add update PO instructions in AGENTS.md
Jiang Xin [Sun, 15 Feb 2026 03:53:27 +0000 (11:53 +0800)] 
l10n: docs: add update PO instructions in AGENTS.md

Add a new section to po/AGENTS.md to provide clear instructions for
updating language-specific PO files. The improved documentation
significantly reduces both conversation turns and execution time.

Performance evaluation with the Qwen model:

    # Before: instructions in po/README.md; the custom prompt
    # references po/README.md during execution
    git-po-helper agent-test --runs=5 --agent=qwen update-po \
        --prompt="Update po/zh_CN.po according to po/README.md"

    # After: instructions in po/AGENTS.md; the built-in prompt
    # references po/AGENTS.md during execution
    git-po-helper agent-test --runs=5 --agent=qwen update-po

Benchmark results (5-run average):

    | Metric      | Before  | After  | Improvement |
    |-------------|---------|--------|-------------|
    | Turns       | 22      | 4      | -82%        |
    | Exec. time  | 38s     | 9s     | -76%        |
    | Turn range  | 17-39   | 3-9    |             |
    | Time range  | 25s-68s | 7s-14s |             |

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agol10n: docs: add AGENTS.md with update POT instructions
Jiang Xin [Sat, 14 Feb 2026 06:08:46 +0000 (14:08 +0800)] 
l10n: docs: add AGENTS.md with update POT instructions

Add a new documentation file po/AGENTS.md that provides agent-specific
instructions for generating or updating po/git.pot, separating them
from the general po/README.md. This separation allows for more targeted
optimization of AI agent workflows.

Performance evaluation with the Qwen model:

    # Before: No agent-specific instructions; use po/README.md for
    # reference.
    git-po-helper agent-test --runs=5 --agent=qwen update-pot \
--prompt="Update po/git.pot according to po/README.md"

    # Phase 1: add the instructions to po/README.md; the prompt
    # references po/README.md during execution
    git-po-helper agent-test --runs=5 --agent=qwen update-pot \
--prompt="Update po/git.pot according to po/README.md"

    # Phase 2: add the instructions to po/AGENTS.md; use the built-in
    # prompt that references po/AGENTS.md during execution
    git-po-helper agent-test --runs=5 --agent=qwen update-pot

Benchmark results (5-run average):

Phase 1 - Optimizing po/README.md:

    | Metric      | Before  | Phase 1 | Improvement |
    |-------------|---------|---------|-------------|
    | Turns       | 17      | 5       | -71%        |
    | Exec. time  | 34s     | 14s     | -59%        |
    | Turn range  | 3-36    | 3-7     |             |
    | Time range  | 10s-59s | 9s-19s  |             |

Phase 2 - Adding po/AGENTS.md (further optimization):

    | Metric      | Before  | Phase 2 | Improvement |
    |-------------|---------|---------|-------------|
    | Turns       | 17      | 3       | -82%        |
    | Exec. time  | 34s     | 8s      | -76%        |
    | Turn range  | 3-36    | 3-3     |             |
    | Time range  | 10s-59s | 6s-9s   |             |

Separating agent-specific instructions into AGENTS.md provides:

- More focused and concise instructions for AI agents
- Cleaner README.md for human readers
- An additional 11% reduction in turns and 17% reduction in execution
  time
- More consistent behavior (turn range reduced from 3-7 to 3-3)

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agol10n: add .gitattributes to simplify location filtering
Jiang Xin [Wed, 4 Feb 2026 03:39:22 +0000 (11:39 +0800)] 
l10n: add .gitattributes to simplify location filtering

To simplify the location filtering process for l10n contributors when
committing po/XX.po files, add filter attributes for selected PO
files to the repository. This ensures all contributors automatically
get the same filter configuration without manual setup in
.git/info/attributes.

The default filter (gettext-no-location) is applied to all .po files
except:

- Legacy, unmaintained PO files that still contain location comments.
  Leaving the filter off avoids index vs working-tree discrepancies for
  these files. The CI pipeline will report an error when future updates
  touch these legacy files.
- Some PO files use a different filter that strips only line numbers
  from location comments while keeping filenames.

Contributors still need to manually define the filter drivers via
git-config as documented in po/README.md.

Four PO files that use location filtering (po/ca.po, po/es.po, po/ga.po,
po/ru.po) were batch-modified so their on-disk format matches the filter
output (e.g. line wrapping), avoiding index vs working-tree mismatch.

Additionally, po/README.md has been reorganized: the material on
preparing location-less PO files for commit has been moved from
"Updating a XX.po file" to a separate "Preparing a XX.po file for
commit" section. This prevents AI agents from introducing unrelated
operations when updating PO files.

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agot9300: work around partial read bug in Dash v0.5.13
Patrick Steinhardt [Thu, 2 Apr 2026 06:51:19 +0000 (08:51 +0200)] 
t9300: work around partial read bug in Dash v0.5.13

When executing t9300 with Dash v0.5.13.1 we can see that the test hangs
completely with the following (condensed) trace:

  git fast-import
  + error=1
  + read output
  + cat input
  + echo checkpoint
  + echo progress checkpoint
  + test rogress checkpoint = progress checkpoint
  + test rogress checkpoint = UNEXPECTED
  + echo cruft: rogress checkpoint
  cruft: rogress checkpoint
  + read output
  + test  = progress checkpoint
  + test  = UNEXPECTED
  + echo cruft:
  cruft:
  + read output

Basically, what's happening here is that we spawn git-fast-import(1) and
wait for it to output a certain string, "progress checkpoint". Curiously
though, what we end up reading is "rogress checkpoint" -- so the first
byte of the expected string is missing.

Same as in the preceding commit, this seems to be a bug in Dash itself
that bisects to c5bf970 (expand: Add multi-byte support to pmatch,
2024-06-02). But other than in the preceding commit, this bug has
already been fixed upstream in 079059a (input: Fix heap-buffer-overflow
in preadbuffer on long lines, 2026-02-11), which is part of v0.5.13.2.

For now though, work around the bug by waiting for the expected output
in a different way. There is no good reason why one version should work
better than the other, but at least the new version doesn't exhibit the
bug. And, if you ask me, it's also slightly easier to read.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot: work around multibyte bug in quoted heredocs with Dash v0.5.13
Patrick Steinhardt [Thu, 2 Apr 2026 06:51:18 +0000 (08:51 +0200)] 
t: work around multibyte bug in quoted heredocs with Dash v0.5.13

When executing our test suite with Dash v0.5.13.2 one can observe
several test failures that all have the same symptoms: we have a quoted
heredoc that contains multibyte characters, but the final data does not
match what we actually wanted to write. One such example is in t0300,
where we see the diffs like the following:

  --- expect-stdout 2026-04-01 07:25:45.249919440 +0000
  +++ stdout 2026-04-01 07:25:45.254919509 +0000
  @@ -1,5 +1,5 @@
   protocol=https
   host=example.com
  -path=perú.git
  +path=perú.git
   username=foo
   password=bar

While seemingly the same, the data that we've written via the heredoc
contains some invisible bytes. The expected hex representation of the
string is:

  7065 72c3 ba2e 6769 74                 per...git

But what we actually get instead is this string:

  7065 7285 02c3 ba02 852e 6769 74       per.......git

What's important to note here is that the multibyte character exists in
both versions. But in the broken version we see that the bytes are
wrapped in a sequence of "85 02" and "02 85". This is the CTLMBCHAR byte
sequence of Dash, which it uses internally to quote multibyte sequences.

As it turns out, this bug was introduced in c5bf970 (expand: Add
multi-byte support to pmatch, 2024-06-02), which adds multibyte support
to more contexts of Dash. One of these contexts seems to be in heredocs,
and Dash _does_ correctly unquote these multibyte sequences when using
an unquoted heredoc. But the bug seems to be that this unquoting does
not happen in quoted heredocs, and the bug still exists on the latest
"master" branch.

For now, work around the bug by using unquoted heredocs instead.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreftable/system: add abstraction to mmap files
Patrick Steinhardt [Thu, 2 Apr 2026 07:31:18 +0000 (09:31 +0200)] 
reftable/system: add abstraction to mmap files

In our codebase we have a couple of wrappers around mmap(3p) that allow
us to reimplement the syscall on platforms that don't have it natively,
like for example Windows. Other projects that embed the reftable library
may have a different infra though to hook up mmap wrappers, but these
are currently hard to integrate.

Provide the infrastructure to let projects easily define the mmap
interface with a custom struct and custom functions.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreftable/system: add abstraction to retrieve time in milliseconds
Patrick Steinhardt [Thu, 2 Apr 2026 07:31:17 +0000 (09:31 +0200)] 
reftable/system: add abstraction to retrieve time in milliseconds

We directly call gettimeofday(3p), which may not be available on some
platforms. Provide the infrastructure to let projects easily use their
own implementations of this function.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreftable/fsck: use REFTABLE_UNUSED instead of UNUSED
Patrick Steinhardt [Thu, 2 Apr 2026 07:31:16 +0000 (09:31 +0200)] 
reftable/fsck: use REFTABLE_UNUSED instead of UNUSED

While we have the reftable-specific `REFTABLE_UNUSED` header, we
accidentally introduced a new usage of the Git-specific `UNUSED` header
into the reftable library in 9051638519 (reftable: add code to
facilitate consistency checks, 2025-10-07).

Convert the site to use `REFTABLE_UNUSED`.

Ideally, we'd move the definition of `UNUSED` into "git-compat-util.h"
so that it becomes in accessible to the reftable library. But this is
unfortunately not easily possible as "compat/mingw-posix.h" requires
this macro, and this header is included by "compat/posix.h".

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreftable/stack: provide fsync(3p) via system header
Patrick Steinhardt [Thu, 2 Apr 2026 07:31:15 +0000 (09:31 +0200)] 
reftable/stack: provide fsync(3p) via system header

Users of the reftable library are expected to provide their own function
callback in cases they want to sync(3p) data to disk via the reftable
write options. But if no such function was provided we end up calling
fsync(3p) directly, which may not even be available on some systems.

While dropping the explicit call to fsync(3p) would work, it would lead
to an unsafe default behaviour where a project may have forgotten to set
up the callback function, and that could lead to potential data loss. So
this is not a great solution.

Instead, drop the callback function and make it mandatory for the
project to define fsync(3p). In the case of Git, we can then easily
inject our custom implementation via the "reftable-system.h" header so
that we continue to use `fsync_component()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreftable: introduce "reftable-system.h" header
Patrick Steinhardt [Thu, 2 Apr 2026 07:31:14 +0000 (09:31 +0200)] 
reftable: introduce "reftable-system.h" header

We're including a couple of standard headers like <stdint.h> in a bunch
of locations, which makes it hard for a project to plug in their own
logic for making required functionality available. For us this is for
example via "compat/posix.h", which already includes all of the system
headers relevant to us.

Introduce a new "reftable-system.h" header that allows projects to
provide their own headers. This new header is supposed to contain all
the project-specific bits to provide the POSIX-like environment, and some
additional supporting code. With this change, we thus have the following
split in our system-specific code:

  - "reftable/reftable-system.h" is the project-specific header that
    provides a POSIX-like environment. Every project is expected to
    provide their own implementation.

  - "reftable/system.h" contains the project-independent definition of
    the interfaces that a project needs to implement. This file should
    not be touched by a project.

  - "reftable/system.c" contains the project-specific implementation of
    the interfaces defined in "system.h". Again, every project is
    expected to provide their own implementation.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorefs/files-backend: drop const to fix strchr() warning
Jeff King [Thu, 2 Apr 2026 04:15:16 +0000 (00:15 -0400)] 
refs/files-backend: drop const to fix strchr() warning

In show_one_reflog_ent(), we're fed a writable strbuf buffer, which we
parse into the various reflog components. We write a NUL over email_end
to tie off one of the fields, and thus email_end must be non-const.

But with a C23 implementation of libc, strchr() will now complain when
assigning the result to a non-const pointer from a const one. So we can
fix this by making the source pointer non-const.

But there's a catch. We derive that source pointer by parsing the line
with parse_oid_hex_algop(), which requires a const pointer for its
out-parameter. We can work around that by teaching it to use our
CONST_OUTPARAM() trick, just like skip_prefix().

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohttp: drop const to fix strstr() warning
Jeff King [Thu, 2 Apr 2026 04:15:14 +0000 (00:15 -0400)] 
http: drop const to fix strstr() warning

In redact_sensitive_header(), a C23 implementation of libc will complain
that strstr() assigns the result from "const char *cookie" to "char
*semicolon".

Ultimately the memory is writable. We're fed a strbuf, generate a const
pointer "sensitive_header" within it using skip_iprefix(), and then
assign the result to "cookie".  So we can solve this by dropping the
const from "cookie" and "sensitive_header".

However, this runs afoul of skip_iprefix(), which wants a "const char
**" for its out-parameter. We can solve that by teaching skip_iprefix()
the same "make sure out is at least as const as in" magic that we
recently taught to skip_prefix().

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorange-diff: drop const to fix strstr() warnings
Jeff King [Thu, 2 Apr 2026 04:15:12 +0000 (00:15 -0400)] 
range-diff: drop const to fix strstr() warnings

This is another case where we implicitly drop the "const" from a pointer
by feeding it to strstr() and assigning the result to a non-const
pointer. This is OK in practice, since the const pointer originally
comes from a writable source (a strbuf), but C23 libc implementations
have started to complain about it.

We do write to the output pointer, so it needs to remain non-const. We
can just switch the input pointer to also be non-const in this case.  By
itself that would run into problems with calls to skip_prefix(), but
since that function has now been taught to match in/out constness
automatically, it just works without us doing anything further.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopkt-line: make packet_reader.line non-const
Jeff King [Thu, 2 Apr 2026 04:15:10 +0000 (00:15 -0400)] 
pkt-line: make packet_reader.line non-const

The "line" member of a packet_reader struct is marked as const. This
kind of makes sense, because it's not its own allocated buffer that
should be freed, and we often use const to indicate that. But it is
always writable, because it points into the non-const "buffer" member.

And we rely on this writability in places like send-pack and
receive-pack, where we parse incoming packet contents by writing NULs
over delimiters. This has traditionally worked because we implicitly
cast away the constness with strchr() like:

  const char *head;
  char *p;

  head = reader->line;
  p = strchr(head, ' ');

Since C23 libc provides a generic strchr() to detect this implicit
const removal, this now generate a compiler warning on some platforms
(like recent glibc).

We can fix it by marking "line" as non-const, as well as a few
intermediate variables (like "head" in the above example). Note that by
itself, switching to a non-const variable would cause problems with this
line in send-pack.c:

  if (!skip_prefix(reader->line, "unpack ", &reader->line))

But due to our skip_prefix() magic introduced in the previous commit,
this compiles fine (both the in and out-parameters are non-const, so we
know it is safe).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoskip_prefix(): check const match between in and out params
Jeff King [Thu, 2 Apr 2026 04:15:07 +0000 (00:15 -0400)] 
skip_prefix(): check const match between in and out params

The skip_prefix() function takes in a "const char *" string, and returns
via a "const char **" out-parameter that points somewhere in that
string. This is fine if you are operating on a const string, like:

  const char *in = ...;
  const char *out;
  if (skip_prefix(in, "foo", &out))
...look at out...

It is also OK if "in" is not const but "out" is, as we add an implicit
const when we pass "in" to the function. But there's another case where
this is limiting. If we want both fields to be non-const, like:

  char *in = ...;
  char *out;
  if (skip_prefix(in, "foo", &out))
*out = '\0';

it doesn't work. The compiler will complain about the type mismatch in
passing "&out" to a parameter which expects "const char **". So to make
this work, we have to do an explicit cast.

But such a cast is ugly, and also means that we run afoul of making this
mistake:

  const char *in = ...;
  char *out;
  if (skip_prefix(in, "foo", (const char **)&out))
*out = '\0';

which causes us to write to the memory pointed by "in", which was const.

We can imagine these four cases as:

  (1) const in, const out
  (2) non-const in, const out
  (3) non-const in, non-const out
  (4) const in, non-const out

Cases (1) and (2) work now. We would like case (3) to work but it
doesn't. But we would like to catch case (4) as a compile error.

So ideally the rule is "the out-parameter must be at least as const as
the in-parameter". We can do this with some macro trickery. We wrap
skip_prefix() in a macro so that it has access to the real types of
in/out. And then we pass those parameters through another macro which:

  1. Fails if the "at least as const" rule is not filled.

  2. Casts to match the signature of the real skip_prefix().

There are a lot of ways to implement the "fails" part. You can use
__builtin_types_compatible_p() to check, and then either our
BUILD_ASSERT macros or _Static_assert to fail. But that requires some
conditional compilation based on compiler feature. That's probably OK
(the fallback would be to just cast without catching case 4). But we can
do better.

The macro I have here uses a ternary with a dead branch that tries to
assign "in" to "out", which should work everywhere and lets the compiler
catch the problem in the usual way. With an input like this:

  int foo(const char *x, const char **y);
  #define foo(in,out) foo((in), CONST_OUTPARAM((in), (out)))

  void ok_const(const char *x, const char **y)
  {
          foo(x, y);
  }

  void ok_nonconst(char *x, char **y)
  {
          foo(x, y);
  }

  void ok_add_const(char *x, const char **y)
  {
          foo(x, y);
  }

  void bad_drop_const(const char *x, char **y)
  {
          foo(x, y);
  }

gcc reports:

  foo.c: In function ‘bad_drop_const’:
  foo.c:2:35: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
      2 |     ((const char **)(0 ? ((*(out) = (in)),(out)) : (out)))
        |                                   ^
  foo.c:4:31: note: in expansion of macro ‘CONST_OUTPARAM’
      4 | #define foo(in,out) foo((in), CONST_OUTPARAM((in), (out)))
        |                               ^~~~~~~~~~~~~~
  foo.c:23:9: note: in expansion of macro ‘foo’
     23 |         foo(x, y);
        |         ^~~

It's a bit verbose, but I think makes it reasonably clear what's going
on. Using BUILD_ASSERT_OR_ZERO() ends up much worse. Using
_Static_assert you can be a bit more informative, but that's not
something we use at all yet in our code-base (it's an old gnu-ism later
standardized in C11).

Our generic macro only works for "const char **", which is something we
could improve by using typeof(in). But that introduces more portability
questions, and also some weird corner cases (e.g., around implicit void
conversion).

This patch just introduces the concept. We'll make use of it in future
patches.

Note that we rename skip_prefix() to skip_prefix_impl() here, to avoid
expanding the macro when defining the function. That's not strictly
necessary since we could just define the macro after defining the inline
function. But that would not be the case for a non-inline function (and
we will apply this technique to them later, and should be consistent).
It also gives us more freedom about where to define the macro. I did so
right above the definition here, which I think keeps the relevant bits
together.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopseudo-merge: fix disk reads from find_pseudo_merge()
Jeff King [Thu, 2 Apr 2026 04:15:05 +0000 (00:15 -0400)] 
pseudo-merge: fix disk reads from find_pseudo_merge()

The goal of this commit was to fix a const warning when compiling
with new versions of glibc, but ended up untangling a much deeper
problem.

The find_pseudo_merge() function does a bsearch() on the "commits"
pointer of a pseudo_merge_map. This pointer ultimately comes from memory
mapped from the on-disk bitmap file, and is thus not writable.

The "commits" array is correctly marked const, but the result from
bsearch() is returned directly as a non-const pseudo_merge_commit
struct. Since new versions of glibc annotate bsearch() in a way that
detects the implicit loss of const, the compiler now warns.

My first instinct was that we should be returning a const struct. That
requires apply_pseudo_merges_for_commit() to mark its local pointer as
const. But that doesn't work! If the offset field has the high-bit set,
we look it up in the extended table via nth_pseudo_merge_ext(). And that
function then feeds our const struct to read_pseudo_merge_commit_at(),
which writes into it by byte-swapping from the on-disk mmap.

But I think this points to a larger problem with find_pseudo_merge(). It
is not just that the return value is missing const, but it is missing
that byte-swapping! And we know that byte-swapping is needed here,
because the comparator we use for bsearch() also calls our
read_pseudo_merge_commit_at() helper.

So I think the interface is all wrong here. We should not be returning a
pointer to a struct which was cast from on-disk data. We should be
filling in a caller-provided struct using the bytes we found,
byte-swapping the values.

That of course raises the dual question: how did this ever work, and
does it work now? The answer to the first part is: this code does not
seem to be triggered in the test suite at all. If we insert a BUG("foo")
call into apply_pseudo_merges_for_commit(), it never triggers.

So I think there is something wrong or missing from the test setup, and
this bears further investigation. Sadly the answer to the second part
("does it work now") is still "no idea". I _think_ this takes us in a
positive direction, but my goal here is mainly to quiet the compiler
warning. Further bug-hunting on this experimental feature can be done
separately.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agofind_last_dir_sep(): convert inline function to macro
Jeff King [Thu, 2 Apr 2026 04:15:03 +0000 (00:15 -0400)] 
find_last_dir_sep(): convert inline function to macro

The find_last_dir_sep() function is implemented as an inline function
which takes in a "const char *" and returns a "char *" via strrchr().
That means that just like strrchr(), it quietly removes the const from
our pointer, which could lead to accidentally writing to the resulting
string.

But C23 versions of libc (including recent glibc) annotate strrchr()
such that the compiler can detect when const is implicitly lost, and it
now complains about the call in this inline function.

We can't just switch the return type of the function to "const char *",
though. Some callers really do want a non-const string to be returned
(and are OK because they are feeding a non-const string into the
function).

The most general solution is for us to annotate find_last_dir_sep() in
the same way that is done for strrchr(). But doing so relies on using
C23 generics, which we do not otherwise require.

Since this inline function is wrapping a single call to strrchr(), we
can take a shortcut. If we implement it as a macro, then the original
type information is still available to strrchr(), and it does the check
for us.

Note that this is just one implementation of find_last_dir_sep(). There
is an alternate implementation in compat/win32/path-utils.h. It doesn't
suffer from the same warning, as it does not use strrchr() and just
casts away const explicitly. That's not ideal, and eventually we may
want to conditionally teach it the same C23 generic trick that strrchr()
uses.  But it has been that way forever, and our goal here is just
quieting new warnings, not improving const-checking.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorun-command: explicitly cast away constness when assigning to void
Jeff King [Thu, 2 Apr 2026 04:15:01 +0000 (00:15 -0400)] 
run-command: explicitly cast away constness when assigning to void

We do this:

  char *equals = strchr(*e, '=');

which implicitly removes the constness from "*e" and cause the compiler
to complain. We never write to "equals", but later assign it to a
string_list util field, which is defined as non-const "void *".

We have to cast somewhere, but doing so at the assignment to util is the
least-bad place, since that is the source of the confusion. Sadly we are
still open to accidentally writing to the string via the util pointer,
but that is the cost of using void pointers, which lose all type
information.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopager: explicitly cast away strchr() constness
Jeff King [Thu, 2 Apr 2026 04:14:58 +0000 (00:14 -0400)] 
pager: explicitly cast away strchr() constness

When we do:

  char *cp = strchr(argv[i], '=');

it implicitly removes the constness from argv[i]. We need "cp" to remain
writable (since we overwrite it with a NUL). In theory we should be able
to drop the const from argv[i], because it is a sub-pointer into our
duplicated pager_env variable.

But we get it from split_cmdline(), which uses the traditional "const
char **" type for argv. This is overly limiting, but changing it would
be awkward for all the other callers of split_cmdline().

Let's do an explicit cast with a note about why it is OK. This is enough
to silence compiler warnings about the implicit const problems.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agotransport-helper: drop const to fix strchr() warnings
Jeff King [Thu, 2 Apr 2026 04:14:56 +0000 (00:14 -0400)] 
transport-helper: drop const to fix strchr() warnings

We implicitly drop the const from our "key" variable when we do:

  char *p = strchr(key, ' ');

which causes compilation with some C23 versions of libc (notably recent
glibc) to complain.

We need "p" to remain writable, since we assign NUL over the space we
found. We can solve this by also making "key" writable. This works
because it comes from a strbuf, which is itself a writable string.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohttp: add const to fix strchr() warnings
Jeff King [Thu, 2 Apr 2026 04:14:51 +0000 (00:14 -0400)] 
http: add const to fix strchr() warnings

The "path" field of a "struct repo" (a custom http-push struct, not to
be confused with "struct repository) is a pointer into a const argv
string, and is never written to.

The compiler does not traditionally complain about assigning from a
const pointer because it happens via strchr(). But with some C23 libc
versions (notably recent glibc), it has started to do so. Let's mark the
field as const to silence the warnings.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoconvert: add const to fix strchr() warnings
Jeff King [Thu, 2 Apr 2026 04:14:49 +0000 (00:14 -0400)] 
convert: add const to fix strchr() warnings

C23 versions of libc (like recent glibc) may provide generic versions of
strchr() that match constness between the input and return value. The
idea being that the compiler can detect when it implicitly converts a
const pointer into a non-const one (which then emits a warning).

There are a few cases here where the result pointer does not need to be
non-const at all, and we should mark it as such. That silences the
warning (and avoids any potential problems with trying to write via
those pointers).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreplay: allow to specify a ref with option --ref
Toon Claes [Wed, 1 Apr 2026 20:55:12 +0000 (22:55 +0200)] 
replay: allow to specify a ref with option --ref

When option '--onto' is passed to git-replay(1), the command will update
refs from the <revision-range> passed to the command. When using option
'--advance' or '--revert', the argument of that option is a ref that
will be updated.

To enable users to specify which ref to update, add option '--ref'. When
using option '--ref', the refs described above are left untouched and
instead the argument of this option is updated instead.

Because this introduces code paths in replay.c that jump to `out` before
init_basic_merge_options() is called on `merge_opt`, zero-initialize the
struct.

Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreplay: use stuck form in documentation and help message
Toon Claes [Wed, 1 Apr 2026 20:55:11 +0000 (22:55 +0200)] 
replay: use stuck form in documentation and help message

gitcli(7) suggests to use stuck form. Change the documentation strings
to use this form.

While at it, reorder them to match the order in the docs.

Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agobuiltin/replay: mark options as not negatable
Toon Claes [Wed, 1 Apr 2026 20:55:10 +0000 (22:55 +0200)] 
builtin/replay: mark options as not negatable

The options '--onto', '--advance', '--revert', and '--ref-action' of
git-replay(1) are not negatable. Mark them as such using
PARSE_OPT_NONEG.

Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoGit 2.54-rc0 v2.54.0-rc0
Junio C Hamano [Thu, 2 Apr 2026 04:31:08 +0000 (21:31 -0700)] 
Git 2.54-rc0

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoRelNotes: minor typo fixes in 2.54.0 draft
Todd Zullinger [Wed, 1 Apr 2026 21:14:36 +0000 (17:14 -0400)] 
RelNotes: minor typo fixes in 2.54.0 draft

Signed-off-by: Todd Zullinger <tmz@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoread-cache: disable renames in add_files_to_cache
Nick Golden [Wed, 1 Apr 2026 19:00:33 +0000 (15:00 -0400)] 
read-cache: disable renames in add_files_to_cache

add_files_to_cache() refreshes the index from worktree changes and does
not need rename detection. When unmerged entries and a deleted stage-0
path are present together, rename detection can pair them and rewrite an
unmerged diff pair to point at the deleted path.

That later makes "git commit -a" and "git add -u" try to stat the
deleted path and die with "unable to stat". Disable rename detection in
this callback-driven staging path and add a regression test covering the
crash.

Signed-off-by: Nick Golden <blindmansion@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot7004: replace wc -l with modern test helpers
Siddharth Shrimali [Wed, 1 Apr 2026 06:20:29 +0000 (11:50 +0530)] 
t7004: replace wc -l with modern test helpers

Pipelines of the form "test $(git tag | wc -l) -eq 0" suppress git's
exit code. This means a crash or unexpected failure from git tag would
go undetected. Additionally, the use of $(...) creates a subshell for
each check, which adds unnecessary overhead.

Replace these patterns with test_must_be_empty and test_line_count.
These helpers check the output of git directly from a file, ensuring
git's exit code is captured properly via the preceding "&&" chain.
They also provide better diagnostics on failure by printing the
contents of the file when a check does not pass.

Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoThe 24th batch
Junio C Hamano [Wed, 1 Apr 2026 17:28:07 +0000 (10:28 -0700)] 
The 24th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'kj/refspec-parsing-outside-repository'
Junio C Hamano [Wed, 1 Apr 2026 17:28:19 +0000 (10:28 -0700)] 
Merge branch 'kj/refspec-parsing-outside-repository'

"git ls-remote '+refs/tags/*:refs/tags/*' https://..." run outside a
repository would dereference a NULL while trying to see if the given
refspec is a single-object refspec, which has been corrected.

* kj/refspec-parsing-outside-repository:
  refspec: fix typo in comment
  remote-curl: fall back to default hash outside repo

2 months agoMerge branch 'jk/t0061-bat-test-update'
Junio C Hamano [Wed, 1 Apr 2026 17:28:19 +0000 (10:28 -0700)] 
Merge branch 'jk/t0061-bat-test-update'

A test to run a .bat file with whitespaces in the name with arguments
with whitespaces in them was flaky in that sometimes it got killed
before it produced expected side effects, which has been rewritten to
make it more robust.

* jk/t0061-bat-test-update:
  t0061: simplify .bat test

2 months agoMerge branch 'mk/repo-help-strings'
Junio C Hamano [Wed, 1 Apr 2026 17:28:19 +0000 (10:28 -0700)] 
Merge branch 'mk/repo-help-strings'

"git repo info -h" and "git repo structure -h" limit their help output
to the part that is specific to the subcommand.

* mk/repo-help-strings:
  repo: show subcommand-specific help text
  repo: factor repo usage strings into shared macros

2 months agoMerge branch 'jc/macos-homebrew-wo-reg-enhanced'
Junio C Hamano [Wed, 1 Apr 2026 17:28:19 +0000 (10:28 -0700)] 
Merge branch 'jc/macos-homebrew-wo-reg-enhanced'

In case homebrew breaks REG_ENHANCED again, leave a in-code comment
to suggest use of our replacement regex as a workaround.

* jc/macos-homebrew-wo-reg-enhanced:
  regexp: leave a pointer to resurrect workaround for Homebrew

2 months agoMerge branch 'rs/use-strvec-pushv'
Junio C Hamano [Wed, 1 Apr 2026 17:28:18 +0000 (10:28 -0700)] 
Merge branch 'rs/use-strvec-pushv'

Code paths that loop over another array to push each element into a
strvec have been rewritten to use strvec_pushv() instead.

* rs/use-strvec-pushv:
  use strvec_pushv() to add another strvec

2 months agoMerge branch 'bk/t5315-test-path-is-helpers'
Junio C Hamano [Wed, 1 Apr 2026 17:28:18 +0000 (10:28 -0700)] 
Merge branch 'bk/t5315-test-path-is-helpers'

Test clean-up.

* bk/t5315-test-path-is-helpers:
  t5315: use test_path_is_file for loose-object check

2 months agoMerge branch 'jk/diff-highlight-more'
Junio C Hamano [Wed, 1 Apr 2026 17:28:18 +0000 (10:28 -0700)] 
Merge branch 'jk/diff-highlight-more'

Various updates to contrib/diff-highlight, including documentation
updates, test improvements, and color configuration handling.

* jk/diff-highlight-more:
  diff-highlight: fetch all config with one process
  diff-highlight: allow module callers to pass in color config
  diff-highlight: test color config
  diff-highlight: use test_decode_color in tests
  t: add matching negative attributes to test_decode_color
  diff-highlight: check diff-highlight exit status in tests
  diff-highlight: drop perl version dependency back to 5.8
  diff-highlight: mention build instructions

2 months agoMerge branch 'vp/http-rate-limit-retries'
Junio C Hamano [Wed, 1 Apr 2026 17:28:18 +0000 (10:28 -0700)] 
Merge branch 'vp/http-rate-limit-retries'

The HTTP transport learned to react to "429 Too Many Requests".

* vp/http-rate-limit-retries:
  http: add support for HTTP 429 rate limit retries
  strbuf_attach: fix call sites to pass correct alloc
  strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()

2 months agoodb: drop unneeded headers and forward decls
Patrick Steinhardt [Tue, 31 Mar 2026 23:57:51 +0000 (01:57 +0200)] 
odb: drop unneeded headers and forward decls

There's a couple of unneeded forward declarations and headers in
"odb.h". Drop these.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoodb: rename `odb_has_object()` flags
Patrick Steinhardt [Tue, 31 Mar 2026 23:57:50 +0000 (01:57 +0200)] 
odb: rename `odb_has_object()` flags

Rename `odb_has_object()` flags to be properly prefixed with the
function name.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoodb: use enum for `odb_write_object` flags
Patrick Steinhardt [Tue, 31 Mar 2026 23:57:49 +0000 (01:57 +0200)] 
odb: use enum for `odb_write_object` flags

We've got a couple of functions that accept `odb_write_object()` flags,
but all of them accept the flags as an `unsigned` integer. In fact, we
don't even have an `enum` for the flags field.

Introduce this `enum` and adapt functions accordingly according to our
coding style.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoodb: rename `odb_write_object()` flags
Patrick Steinhardt [Tue, 31 Mar 2026 23:57:48 +0000 (01:57 +0200)] 
odb: rename `odb_write_object()` flags

Rename `odb_write_object()` flags to be properly prefixed with the
function name.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agotreewide: use enum for `odb_for_each_object()` flags
Patrick Steinhardt [Tue, 31 Mar 2026 23:57:47 +0000 (01:57 +0200)] 
treewide: use enum for `odb_for_each_object()` flags

We've got a couple of callsites where we pass `odb_for_each_object()`
flags, but accept an `unsigned` flags field instead of the corresponding
enum. Adapt these to accept the enum type instead.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoCodingGuidelines: document our style for flags
Patrick Steinhardt [Tue, 31 Mar 2026 23:57:46 +0000 (01:57 +0200)] 
CodingGuidelines: document our style for flags

We have recently iterated a bit on our style for flags. Document this.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'ps/odb-generic-object-name-handling' into ps/odb-cleanup
Junio C Hamano [Wed, 1 Apr 2026 03:43:06 +0000 (20:43 -0700)] 
Merge branch 'ps/odb-generic-object-name-handling' into ps/odb-cleanup

* ps/odb-generic-object-name-handling:
  odb: introduce generic `odb_find_abbrev_len()`
  object-file: move logic to compute packed abbreviation length
  object-name: move logic to compute loose abbreviation length
  object-name: simplify computing common prefixes
  object-name: abbreviate loose object names without `disambiguate_state`
  object-name: merge `update_candidates()` and `match_prefix()`
  object-name: backend-generic `get_short_oid()`
  object-name: backend-generic `repo_collect_ambiguous()`
  object-name: extract function to parse object ID prefixes
  object-name: move logic to iterate through packed prefixed objects
  object-name: move logic to iterate through loose prefixed objects
  odb: introduce `struct odb_for_each_object_options`
  oidtree: extend iteration to allow for arbitrary return codes
  oidtree: modernize the code a bit
  object-file: fix sparse 'plain integer as NULL pointer' error

2 months agocache-tree: use index state repository in trace2 calls
Jayesh Daga [Tue, 31 Mar 2026 10:02:53 +0000 (10:02 +0000)] 
cache-tree: use index state repository in trace2 calls

trace2 calls in cache-tree.c use the global 'the_repository',
even though cache_tree_update() has access to an explicit
repository pointer via 'istate->repo'.

Using the global repository can result in incorrect trace2
output when multiple repository instances are in use, as
events may be attributed to the wrong repository.

Use 'istate->repo' in cache_tree_update() to ensure correct
repository attribution.

Other call sites are left unchanged as they do not have
access to a repository instance.

Signed-off-by: Jayesh Daga <jayeshdaga99@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoThe 23rd batch
Junio C Hamano [Mon, 30 Mar 2026 20:56:44 +0000 (13:56 -0700)] 
The 23rd batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'ai/t2107-test-path-is-helpers'
Junio C Hamano [Mon, 30 Mar 2026 20:57:03 +0000 (13:57 -0700)] 
Merge branch 'ai/t2107-test-path-is-helpers'

Test cleanup.

* ai/t2107-test-path-is-helpers:
  t2107: modernize path existence check

2 months agoMerge branch 'jw/object-name-bitset-to-enum'
Junio C Hamano [Mon, 30 Mar 2026 20:57:02 +0000 (13:57 -0700)] 
Merge branch 'jw/object-name-bitset-to-enum'

The unsigned integer that is used as an bitset to specify the kind
of branches interpret_branch_name() function has been changed to
use a dedicated enum type.

* jw/object-name-bitset-to-enum:
  object-name: turn INTERPRET_BRANCH_* constants into enum values

2 months agoMerge branch 'jw/t2203-status-pipe-fix'
Junio C Hamano [Mon, 30 Mar 2026 20:57:01 +0000 (13:57 -0700)] 
Merge branch 'jw/t2203-status-pipe-fix'

Test clean-up.

* jw/t2203-status-pipe-fix:
  t2203: avoid suppressing git status exit code

2 months agoMerge branch 'jw/apply-corrupt-location'
Junio C Hamano [Mon, 30 Mar 2026 20:57:00 +0000 (13:57 -0700)] 
Merge branch 'jw/apply-corrupt-location'

"git apply" now reports the name of the input file along with the
line number when it encounters a corrupt patch, and correctly
resets the line counter when processing multiple patch files.

* jw/apply-corrupt-location:
  apply: report input location in binary and garbage patch errors
  apply: report input location in header parsing errors
  apply: report the location of corrupt patches

2 months agoMerge branch 'rs/split-index-the-repo-fix'
Junio C Hamano [Mon, 30 Mar 2026 20:56:59 +0000 (13:56 -0700)] 
Merge branch 'rs/split-index-the-repo-fix'

split-index.c has been updated to not use the global the_repository
and the_hash_algo variables.

* rs/split-index-the-repo-fix:
  split-index: stop using the_repository and the_hash_algo

2 months agoMerge branch 'rs/ahead-behind-cleanup-optimization'
Junio C Hamano [Mon, 30 Mar 2026 20:56:58 +0000 (13:56 -0700)] 
Merge branch 'rs/ahead-behind-cleanup-optimization'

The cleanup of remaining bitmaps in "ahead_behind()" has been
simplified.

* rs/ahead-behind-cleanup-optimization:
  commit-reach: simplify cleanup of remaining bitmaps in ahead_behind ()

2 months agoread-cache: use istate->repo for trace2 logging
Jayesh Daga [Mon, 30 Mar 2026 18:38:06 +0000 (18:38 +0000)] 
read-cache: use istate->repo for trace2 logging

trace2 calls in read-cache.c use the global 'the_repository',
even though the relevant index_state provides an explicit
repository pointer via 'istate->repo'.

Using the global repository can result in incorrect trace2
output when multiple repository instances are in use, as
events may be attributed to the wrong repository.

Use 'istate->repo' instead to ensure correct repository
attribution.

Signed-off-by: Jayesh Daga <jayeshdaga99@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreceive-pack: use worktree HEAD for updateInstead
Pablo Sabater [Mon, 30 Mar 2026 11:18:22 +0000 (13:18 +0200)] 
receive-pack: use worktree HEAD for updateInstead

When a bare repo has linked worktrees, and its HEAD points to an unborn branch,
pushing to a wt branch with updateInstead fails and rejects the push, even if
the wt is clean. This happens because HEAD is checked only for the bare repo
context, instead of the wt.

Remove head_has_history and check for worktree->head_oid which does
have the correct HEAD of the wt.

Update the test added by Runxi's patch to expect success.

Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot5516: clean up cloned and new-wt in denyCurrentBranch and worktrees test
Pablo Sabater [Mon, 30 Mar 2026 11:18:21 +0000 (13:18 +0200)] 
t5516: clean up cloned and new-wt in denyCurrentBranch and worktrees test

The 'denyCurrentBranch and worktrees' test creates a 'cloned' and a 'new-wt'
but it doesn't clean them after the test. This makes other tests that use
the same name after this one to fail.

Add test_when_finished to clean them at the end.

Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot5516: test updateInstead with worktree and unborn bare HEAD
Runxi Yu [Mon, 30 Mar 2026 11:18:20 +0000 (13:18 +0200)] 
t5516: test updateInstead with worktree and unborn bare HEAD

This is a regression test which should presently fail, to demonstrate
the behavior I encountered that looks like a bug.

When a bare repository has a worktree checked out on a separate branch,
receive.denyCurrentBranch=updateInstead should allow a push to that
branch and update the linked worktree, as long as the linked worktree is
clean.

But, if the bare repository's own HEAD is repointed to an unborn branch,
the push is rejected with "Working directory has staged changes", even
though the linked worktree itself is clean.

This test is essentially a minimal working example of what I encountered
while actually using Git; it might not be the optimal way to demonstrate
the underlying bug. I suspect builtin/receive-pack.c is using the bare
repository's HEAD even when comparing it to the worktree's index.

Signed-off-by: Runxi Yu <me@runxiyu.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodocs: fix "git stash [push]" documentation
Quentin Bernet [Mon, 30 Mar 2026 13:24:35 +0000 (13:24 +0000)] 
docs: fix "git stash [push]" documentation

Both the synopsis and explanation are incorrect and contradict each
other.
The synopsis claims "push" can only be omitted when you do not give any
options and arguments.
The explanation correctly claims that non-option arguments are not
allowed, except pathspec elements preceded by double hyphens.
But it also adds "-p" to the list of exceptions, even though it is an
option argument.

Signed-off-by: Quentin Bernet <quentin.bernet@bluewin.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agograph: add truncation mark to capped lanes
Pablo Sabater [Sat, 28 Mar 2026 00:11:13 +0000 (01:11 +0100)] 
graph: add truncation mark to capped lanes

When lanes are hidden by --graph-lane-limit, show a "~"
truncation mark, so users know that there are lanes
being truncated. The "~" is chosen because it is not
used elsewhere in the graph and it is discrete.

Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>