]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
2 months agohook: allow hook.jobs=-1 to use all available CPU cores
Adrian Ratiu [Fri, 10 Apr 2026 09:06:07 +0000 (12:06 +0300)] 
hook: allow hook.jobs=-1 to use all available CPU cores

Allow -1 as a value for hook.jobs, hook.<event>.jobs, and the -j
CLI flag to mean "use as many jobs as there are CPU cores", matching
the convention used by fetch.parallel and other Git subsystems.

The value is resolved to online_cpus() at parse time so the rest
of the code always works with a positive resolved count.

Other non-positive values (0, -2, etc) are rejected with a warning
(config) or die (CLI).

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: add hook.<event>.enabled switch
Adrian Ratiu [Fri, 10 Apr 2026 09:06:06 +0000 (12:06 +0300)] 
hook: add hook.<event>.enabled switch

Add a hook.<event>.enabled config key that disables all hooks for
a given event, when set to false, acting as a high-level switch
above the existing per-hook hook.<friendly-name>.enabled.

Event-disabled hooks are shown in "git hook list" with an
"event-disabled" tab-separated prefix before the name:

$ git hook list test-hook
event-disabled  hook-1
event-disabled  hook-2

With --show-scope:

$ git hook list --show-scope test-hook
local   event-disabled  hook-1

When a hook is both per-hook disabled and event-disabled, only
"event-disabled" is shown: the event-level switch is the more
relevant piece of information, and the per-hook "disabled" status
will surface once the event is re-enabled.

Using an event name as a friendly-name (e.g. hook.<event>.enabled)
can cause ambiguity, so a fatal error is issued when using a known
event name and a warning is issued for unknown event name, since
a collision cannot be detected with certainty for unknown events.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: move is_known_hook() to hook.c for wider use
Adrian Ratiu [Fri, 10 Apr 2026 09:06:05 +0000 (12:06 +0300)] 
hook: move is_known_hook() to hook.c for wider use

Move is_known_hook() from builtin/hook.c (static) into hook.c and
export it via hook.h so it can be reused.

Make it return bool and the iterator `h` for clarity (iterate hooks).

Both meson.build and the Makefile are updated to reflect that the
header is now used by libgit, not the builtin sources.

The next commit will use this to reject hook friendly-names that
collide with known event names.

Co-authored-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: warn when hook.<friendly-name>.jobs is set
Adrian Ratiu [Fri, 10 Apr 2026 09:06:04 +0000 (12:06 +0300)] 
hook: warn when hook.<friendly-name>.jobs is set

Issue a warning when the user confuses the hook process and event
namespaces by setting hook.<friendly-name>.jobs.

Detect this by checking whether the name carrying .jobs also has
.command, .event, or .parallel configured.  Extract is_friendly_name()
as a helper for this check, to be reused by future per-event config
handling.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: add per-event jobs config
Adrian Ratiu [Fri, 10 Apr 2026 09:06:03 +0000 (12:06 +0300)] 
hook: add per-event jobs config

Add a hook.<event>.jobs count config that allows users to override the
global hook.jobs setting for specific hook events.

This allows finer-grained control over parallelism on a per-event basis.

For example, to run `post-receive` hooks with up to 4 parallel jobs
while keeping other events at their global default:

[hook]
    post-receive.jobs = 4

Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: add -j/--jobs option to git hook run
Emily Shaffer [Fri, 10 Apr 2026 09:06:02 +0000 (12:06 +0300)] 
hook: add -j/--jobs option to git hook run

Expose the parallel job count as a command-line flag so callers can
request parallelism without relying only on the hook.jobs config.

Add tests covering serial/parallel execution and TTY behaviour under
-j1 vs -jN.

Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: mark non-parallelizable hooks
Emily Shaffer [Fri, 10 Apr 2026 09:06:01 +0000 (12:06 +0300)] 
hook: mark non-parallelizable hooks

Several hooks are known to be inherently non-parallelizable, so initialize
them with RUN_HOOKS_OPT_INIT_FORCE_SERIAL. This pins jobs=1 and overrides
any hook.jobs or runtime -j flags.

These hooks are:
applypatch-msg, pre-commit, prepare-commit-msg, commit-msg, post-commit,
post-checkout, and push-to-checkout.

Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: allow pre-push parallel execution
Adrian Ratiu [Fri, 10 Apr 2026 09:06:00 +0000 (12:06 +0300)] 
hook: allow pre-push parallel execution

pre-push is the only hook that keeps stdout and stderr separate (for
backwards compatibility with git-lfs and potentially other users). This
prevents parallelizing it because run-command needs stdout_to_stderr=1
to buffer and de-interleave parallel outputs.

Since we now default to jobs=1, backwards compatibility is maintained
without needing any extension or extra config: when no parallelism is
requested, pre-push behaves exactly as before.

When the user explicitly opts into parallelism via hook.jobs > 1,
hook.<event>.jobs > 1, or -jN, they accept the changed output behavior.

Document this and let get_hook_jobs() set stdout_to_stderr=1 automatically
when jobs > 1, removing the need for any extension infrastructure.

Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: allow parallel hook execution
Emily Shaffer [Fri, 10 Apr 2026 09:05:59 +0000 (12:05 +0300)] 
hook: allow parallel hook execution

Hooks always run in sequential order due to the hardcoded jobs == 1
passed to run_process_parallel(). Remove that hardcoding to allow
users to run hooks in parallel (opt-in).

Users need to decide which hooks to run in parallel, by specifying
"parallel = true" in the config, because Git cannot know if their
specific hooks are safe to run or not in parallel (for e.g. two hooks
might write to the same file or call the same program).

Some hooks are unsafe to run in parallel by design: these will marked
in the next commit using RUN_HOOKS_OPT_INIT_FORCE_SERIAL.

The hook.jobs config specifies the default number of jobs applied to all
hooks which have parallelism enabled.

Signed-off-by: Emily Shaffer <emilyshaffer@google.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: parse the hook.jobs config
Adrian Ratiu [Fri, 10 Apr 2026 09:05:58 +0000 (12:05 +0300)] 
hook: parse the hook.jobs config

The hook.jobs config is a global way to set hook parallelization for
all hooks, in the sense that it is not per-event nor per-hook.

Finer-grained configs will be added in later commits which can override
it, for e.g. via a per-event type job options. Next commits will also
add to this item's documentation.

Parse hook.jobs config key in hook_config_lookup_all() and store its
value in hook_all_config_cb.jobs, then transfer it into r->jobs after
the config pass completes.

This is mostly plumbing and the cached value is not yet used.

Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoconfig: add a repo_config_get_uint() helper
Adrian Ratiu [Fri, 10 Apr 2026 09:05:57 +0000 (12:05 +0300)] 
config: add a repo_config_get_uint() helper

Next commits add a 'hook.jobs' config option of type 'unsigned int',
so add a helper to parse it since the API only supports int and ulong.

An alternative is to make 'hook.jobs' an 'int' or parse it as an 'int'
then cast it to unsigned, however it's better to use proper helpers for
the type. Using 'ulong' is another option which already has helpers, but
it's a bit excessive in size for just the jobs number.

Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorepository: fix repo_init() memleak due to missing _clear()
Adrian Ratiu [Fri, 10 Apr 2026 09:05:56 +0000 (12:05 +0300)] 
repository: fix repo_init() memleak due to missing _clear()

There is an old pre-existing memory leak in repo_init() due to failing
to call clear_repository_format() in the error case.

It went undetected because a specific bug is required to trigger it:
enable a v1 extension in a repository with format v0. Obviously this
can only happen in a development environment, so it does not trigger
in normal usage, however the memleak is real and needs fixing.

Fix it by also calling clear_repository_format() in the error case.

Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agol10n: zh_CN: post-2.53 code review
Jiang Xin [Thu, 5 Feb 2026 01:21:28 +0000 (09:21 +0800)] 
l10n: zh_CN: post-2.53 code review

Update Simplified Chinese translation for post-2.53 code review.

Reviewed-by: 依云 <lilydjwg@gmail.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agoEnable Rust by default
brian m. carlson [Thu, 9 Apr 2026 22:44:34 +0000 (22:44 +0000)] 
Enable Rust by default

Our breaking changes document says that we'll enable Rust by default in
Git 2.54.  Adjust the Makefile to switch the option from WITH_RUST to
NO_RUST to enable it by default and update the help text accordingly.
Similarly, for Meson, enable the option by default and do not
automatically disable it if Cargo is missing, since the goal is to help
users find where they are likely to have problems in the future.

Update our CI tests to swap out the single Linux job with Rust to a
single job without, both for Makefile and Meson.  Similarly, update the
Windows Makefile job to not use Rust, while the Meson job (which does
not build with ci/lib.sh) will default to having it enabled.

Move the check for Cargo in the Meson build because it is no longer
needed in the main script.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoLinux: link against libdl
brian m. carlson [Thu, 9 Apr 2026 22:44:33 +0000 (22:44 +0000)] 
Linux: link against libdl

Older versions of Rust on Linux, such as that used in Debian 11 in our
CI, require linking against libdl.  Were we linking with Cargo, this
would be included automatically, but since we're not, explicitly set it
in the system-specific config.

This library is part of libc, so linking against it if it happens to be
unnecessary will add no dependencies to the resulting binary.  In
addition, it is provided by both glibc and musl, so it should be
portable to almost all Linux systems.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoci: install cargo on Alpine
brian m. carlson [Thu, 9 Apr 2026 22:44:32 +0000 (22:44 +0000)] 
ci: install cargo on Alpine

We'll make Rust the default in a future commit, so be sure to install
Cargo (which will also install Rust) to prepare for that case.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodocs: update version with default Rust support
brian m. carlson [Thu, 9 Apr 2026 22:44:31 +0000 (22:44 +0000)] 
docs: update version with default Rust support

We missed the cut-off for Rust by default in 2.53, but we still can
enable it by default for 2.54, so update our breaking changes document
accordingly.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agowritev: retract the topic until we have a better emulation
Junio C Hamano [Thu, 9 Apr 2026 22:07:12 +0000 (15:07 -0700)] 
writev: retract the topic until we have a better emulation

The emulation layer we added for writev(3p) tries to be too faithful
to the spec that on systems with SSIZE_MAX set to lower than 64kB to
fit a single sideband packet would fail just like the real system
writev(), which makes our use of writev() for sideband messages
unworkable.

Let's revert them and reboot the effort after the release.  The
reverted commits are:

    $ git log -Swritev --oneline 8023abc632^..v2.52.0-rc1
    89152af176 cmake: use writev(3p) wrapper as needed
    26986f4cba sideband: use writev(3p) to send pktlines
    1970fcef93 wrapper: introduce writev(3p) wrappers
    3b9b2c2a29 compat/posix: introduce writev(3p) wrapper

8023abc632 is the merge of ps/upload-pack-buffer-more-writes topic to
the mainline.

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoRevert "compat/posix: introduce writev(3p) wrapper"
Junio C Hamano [Thu, 9 Apr 2026 21:48:24 +0000 (14:48 -0700)] 
Revert "compat/posix: introduce writev(3p) wrapper"

This reverts commit 3b9b2c2a29a1d529ca9884fa0a6529f6e2496abe; let's
not use writev() for now.

2 months agoRevert "wrapper: introduce writev(3p) wrappers"
Junio C Hamano [Thu, 9 Apr 2026 21:48:09 +0000 (14:48 -0700)] 
Revert "wrapper: introduce writev(3p) wrappers"

This reverts commit 1970fcef93adcc5a35f6468d00a5a634d5af2b3c; let's
not use writev() for now.

2 months agoRevert "sideband: use writev(3p) to send pktlines"
Junio C Hamano [Thu, 9 Apr 2026 21:47:51 +0000 (14:47 -0700)] 
Revert "sideband: use writev(3p) to send pktlines"

This reverts commit 26986f4cbaf38d84a82b0b35da211389ce49552c; let's
not use writev() for now.

2 months agoRevert "cmake: use writev(3p) wrapper as needed"
Junio C Hamano [Thu, 9 Apr 2026 21:47:28 +0000 (14:47 -0700)] 
Revert "cmake: use writev(3p) wrapper as needed"

This reverts commit 89152af176ea94ea8f3249115b6e00827fbbeb70; let's
not use writev() for now.

2 months agoA bit more for -rc2
Junio C Hamano [Thu, 9 Apr 2026 18:21:36 +0000 (11:21 -0700)] 
A bit more for -rc2

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'ds/rev-list-maximal-only-optim'
Junio C Hamano [Thu, 9 Apr 2026 18:21:59 +0000 (11:21 -0700)] 
Merge branch 'ds/rev-list-maximal-only-optim'

"git rev-list --maximal-only" has been optimized by borrowing the
logic used by "git show-branch --independent", which computes the
same kind of information much more efficiently.

* ds/rev-list-maximal-only-optim:
  rev-list: use reduce_heads() for --maximal-only
  p6011: add perf test for rev-list --maximal-only
  t6600: test --maximal-only and --independent

2 months agoMerge branch 'kh/doc-config-list'
Junio C Hamano [Thu, 9 Apr 2026 18:21:59 +0000 (11:21 -0700)] 
Merge branch 'kh/doc-config-list'

"git config list" is the official way to spell "git config -l" and
"git config --list".  Use it to update the documentation.

* kh/doc-config-list:
  doc: gitcvs-migration: rephrase “man page”
  doc: replace git config --list/-l with `list`

2 months agoMerge branch 'jk/c23-const-preserving-fixes-more'
Junio C Hamano [Thu, 9 Apr 2026 18:21:59 +0000 (11:21 -0700)] 
Merge branch 'jk/c23-const-preserving-fixes-more'

Further work to adjust the codebase for C23 that changes functions
like strchr() that discarded constness when they return a pointer into
a const string to preserve constness.

* jk/c23-const-preserving-fixes-more:
  git-compat-util: fix CONST_OUTPARAM typo and indentation
  refs/files-backend: drop const to fix strchr() warning
  http: drop const to fix strstr() warning
  range-diff: drop const to fix strstr() warnings
  pkt-line: make packet_reader.line non-const
  skip_prefix(): check const match between in and out params
  pseudo-merge: fix disk reads from find_pseudo_merge()
  find_last_dir_sep(): convert inline function to macro
  run-command: explicitly cast away constness when assigning to void
  pager: explicitly cast away strchr() constness
  transport-helper: drop const to fix strchr() warnings
  http: add const to fix strchr() warnings
  convert: add const to fix strchr() warnings

2 months agoMerge branch 'master' of https://github.com/git/git
Jiang Xin [Thu, 9 Apr 2026 05:48:26 +0000 (13:48 +0800)] 
Merge branch 'master' of https://github.com/git/git

Upstream adds 8 new translatable messages.

* 'master' of https://github.com/git/git: (93 commits)
  A bit more post -rc1
  ...

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2 months agoarchive: document --prefix handling of absolute and parent paths
Pushkar Singh [Wed, 8 Apr 2026 16:00:06 +0000 (16:00 +0000)] 
archive: document --prefix handling of absolute and parent paths

Clarify that --prefix is used as given and is not normalized,
and may include leading slashes or parent directory components.

Signed-off-by: Pushkar Singh <pushkarkumarsingh1970@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoA bit more post -rc1
Junio C Hamano [Wed, 8 Apr 2026 18:00:10 +0000 (11:00 -0700)] 
A bit more post -rc1

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorun_processes_parallel(): fix order of sigpipe handling
Jeff King [Wed, 8 Apr 2026 17:20:55 +0000 (13:20 -0400)] 
run_processes_parallel(): fix order of sigpipe handling

In commit ec0becacc9 (run-command: add stdin callback for
parallelization, 2026-01-28), we taught run_processes_parallel() to
ignore SIGPIPE, since we wouldn't want a write() to a broken pipe of one
of the children to take down the whole process.

But there's a subtle ordering issue. After we ignore SIGPIPE, we call
pp_init(), which installs its own cleanup handler for multiple signals
using sigchain_push_common(), which includes SIGPIPE. So if we receive
SIGPIPE while writing to a child, we'll trigger that handler first, pop
it off the stack, and then re-raise (which is then ignored because of
the SIG_IGN we pushed first).

But what does that handler do? It tries to clean up all of the child
processes, under the assumption that when we re-raise the signal we'll
be exiting the process!

So a hook that exits without reading all of its input will cause us to
get SIGPIPE, which will put us in a signal handler that then tries to
kill() that same child.

This seems to be mostly harmless on Linux. The process has already
exited by this point, and though kill() does not complain (since the
process has not been reaped with a wait() call), it does not affect the
exit status of the process.

However, this seems not to be true on all platforms. This case is
triggered by t5401.13, "pre-receive hook that forgets to read its
input". This test fails on NonStop since that hook was converted to the
run_processes_parallel() API.

We can fix it by reordering the code a bit. We should run pp_init()
first, and then push our SIG_IGN onto the stack afterwards, so that it
is truly ignored while feeding the sub-processes.

Note that we also reorder the popping at the end of the function, too.
This is not technically necessary, as we are doing two pops either way,
but now the pops will correctly match their pushes.

This also fixes a related case that we can't test yet. If we did have
more than one process to run, then one child causing SIGPIPE would cause
us to kill() all of the children (which might still actually be
running). But the hook API is the only user of the new feed_pipe
feature, and it does not yet support parallel hook execution. So for now
we'll always execute the processes sequentially. Once parallel hook
execution exists, we'll be able to add a test which covers this.

Reported-by: Randall S. Becker <rsbecker@nexbridge.com>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'jt/index-fd-wo-repo-regression-fix'
Junio C Hamano [Wed, 8 Apr 2026 17:20:51 +0000 (10:20 -0700)] 
Merge branch 'jt/index-fd-wo-repo-regression-fix'

During Git 2.52 timeframe, we broke streaming computation of object
hash outside a repository, which has been corrected.

* jt/index-fd-wo-repo-regression-fix:

2 months agoMerge branch 'jt/index-fd-wo-repo-regression-fix-maint'
Junio C Hamano [Wed, 8 Apr 2026 17:20:51 +0000 (10:20 -0700)] 
Merge branch 'jt/index-fd-wo-repo-regression-fix-maint'

During Git 2.52 timeframe, we broke streaming computation of object
hash outside a repository, which has been corrected.

* jt/index-fd-wo-repo-regression-fix-maint:
  object-file: avoid ODB transaction when not writing objects

2 months agoMerge branch 'tc/replay-ref'
Junio C Hamano [Wed, 8 Apr 2026 17:19:18 +0000 (10:19 -0700)] 
Merge branch 'tc/replay-ref'

The experimental `git replay` command learned the `--ref=<ref>` option
to allow specifying which ref to update, overriding the default behavior.

* tc/replay-ref:
  replay: allow to specify a ref with option --ref
  replay: use stuck form in documentation and help message
  builtin/replay: mark options as not negatable

2 months agoMerge branch 'ng/add-files-to-cache-wo-rename'
Junio C Hamano [Wed, 8 Apr 2026 17:19:17 +0000 (10:19 -0700)] 
Merge branch 'ng/add-files-to-cache-wo-rename'

add_files_to_cache() used diff_files() to detect only the paths that
are different between the index and the working tree and add them,
which does not need rename detection, which interfered with unnecessary
conflicts.

* ng/add-files-to-cache-wo-rename:
  read-cache: disable renames in add_files_to_cache

2 months agoMerge branch 'ps/reftable-portability'
Junio C Hamano [Wed, 8 Apr 2026 17:19:17 +0000 (10:19 -0700)] 
Merge branch 'ps/reftable-portability'

Update reftable library part with what is used in libgit2 to improve
portability to different target codebases and platforms.

* ps/reftable-portability:
  reftable/system: add abstraction to mmap files
  reftable/system: add abstraction to retrieve time in milliseconds
  reftable/fsck: use REFTABLE_UNUSED instead of UNUSED
  reftable/stack: provide fsync(3p) via system header
  reftable: introduce "reftable-system.h" header

2 months agoMerge branch 'jd/cache-tree-trace-wo-the-repository'
Junio C Hamano [Wed, 8 Apr 2026 17:19:17 +0000 (10:19 -0700)] 
Merge branch 'jd/cache-tree-trace-wo-the-repository'

Code cleanup.

* jd/cache-tree-trace-wo-the-repository:
  cache-tree: use index state repository in trace2 calls

2 months agoMerge branch 'ps/odb-cleanup'
Junio C Hamano [Wed, 8 Apr 2026 17:19:17 +0000 (10:19 -0700)] 
Merge branch 'ps/odb-cleanup'

Various code clean-up around odb subsystem.

* ps/odb-cleanup:
  odb: drop unneeded headers and forward decls
  odb: rename `odb_has_object()` flags
  odb: use enum for `odb_write_object` flags
  odb: rename `odb_write_object()` flags
  treewide: use enum for `odb_for_each_object()` flags
  CodingGuidelines: document our style for flags

2 months agoMerge branch 'ss/t7004-unhide-git-failures'
Junio C Hamano [Wed, 8 Apr 2026 17:19:15 +0000 (10:19 -0700)] 
Merge branch 'ss/t7004-unhide-git-failures'

Test clean-up.

* ss/t7004-unhide-git-failures:
  t7004: replace wc -l with modern test helpers

2 months agot1800: add &&-chains to test helper functions
Adrian Ratiu [Wed, 8 Apr 2026 16:11:48 +0000 (19:11 +0300)] 
t1800: add &&-chains to test helper functions

Add the missing &&'s so we properly propagate failures
between commands in the hook helper functions.

Also add a missing mkdir -p arg (found by adding the &&).

Reported-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorefs/reftable-backend: drop uses of the_repository
Shreyansh Paliwal [Sat, 4 Apr 2026 13:58:40 +0000 (19:28 +0530)] 
refs/reftable-backend: drop uses of the_repository

reftable_be_init() and reftable_be_create_on_disk() use the_repository even
though a repository instance is already available, either directly or via
struct ref_store.

Replace these uses with the appropriate local repository instance (repo or
ref_store->repo) to avoid relying on global state.

Note that USE_THE_REPOSITORY_VARIABLE cannot be removed yet, as
is_bare_repository() is still there in the file.

Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorefs: remove the_hash_algo global state
Shreyansh Paliwal [Sat, 4 Apr 2026 13:58:39 +0000 (19:28 +0530)] 
refs: remove the_hash_algo global state

refs.c uses the_hash_algo in multiple places, relying on global state for
the object hash algorithm. Replace these uses with the appropriate
repository-specific hash_algo. In transaction-related functions
(ref_transaction_create, ref_transaction_delete, migrate_one_ref, and
transaction_hook_feed_stdin), use transaction->ref_store->repo->hash_algo.
In other cases, such as repo_get_submodule_ref_store(), use
repo->hash_algo.

Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorefs: add struct repository parameter in get_files_ref_lock_timeout_ms()
Shreyansh Paliwal [Sat, 4 Apr 2026 13:58:38 +0000 (19:28 +0530)] 
refs: add struct repository parameter in get_files_ref_lock_timeout_ms()

get_files_ref_lock_timeout_ms() calls repo_config_get_int() using
the_repository, as no repository instance is available in its scope. Add a
struct repository parameter and use it instead of the_repository.

Update all callers accordingly. In files-backend.c, lock_raw_ref() can
obtain repository instance from the struct ref_transaction via
transaction->ref_store->repo and pass it down. For create_reflock(), which
is used as a callback, introduce a small wrapper struct to pass both struct
lock_file and struct repository through the callback data.

This reduces reliance on the_repository global, though the function
still uses static variables and is not yet fully repository-scoped.
This can be addressed in a follow-up change.

Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoGit 2.54-rc1 v2.54.0-rc1
Junio C Hamano [Wed, 8 Apr 2026 15:21:34 +0000 (08:21 -0700)] 
Git 2.54-rc1

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodocs: correct information about reftable
brian m. carlson [Thu, 2 Apr 2026 22:42:41 +0000 (22:42 +0000)] 
docs: correct information about reftable

Our description of the reftable format is that it is experimental and
subject to change, but that is no longer true.  Remove this statement so
as not to mislead users.

In addition, the documentation says that the files format is the
default, but that is not true if breaking changes mode is on.  Correct
this information with a conditional.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'jt/index-fd-wo-repo-regression-fix-maint' into HEAD
Junio C Hamano [Wed, 8 Apr 2026 00:34:30 +0000 (17:34 -0700)] 
Merge branch 'jt/index-fd-wo-repo-regression-fix-maint' into HEAD

* jt/index-fd-wo-repo-regression-fix-maint:
  object-file: avoid ODB transaction when not writing objects

2 months agoobject-file: avoid ODB transaction when not writing objects
Justin Tobler [Tue, 7 Apr 2026 20:17:30 +0000 (15:17 -0500)] 
object-file: avoid ODB transaction when not writing objects

In ce1661f9da (odb: add transaction interface, 2025-09-16), existing
ODB transaction logic is adapted to create a transaction interface
at the ODB layer. The intent here is for the ODB transaction
interface to eventually provide an object source agnostic means to
manage transactions.

An unintended consequence of this change though is that
`object-file.c:index_fd()` may enter the ODB transaction path even
when no object write is requested. In non-repository contexts, this
can result in a NULL dereference and segfault. One such case occurs
when running git-diff(1) outside of a repository with
"core.bigFileThreshold" forcing the streaming path in `index_fd()`:

        $ echo foo >foo
        $ echo bar >bar
        $ git -c core.bigFileThreshold=1 diff -- foo bar

In this scenario, the caller only needs to compute the object ID. Object
hashing does not require an ODB, so starting a transaction is both
unnecessary and invalid.

Fix the bug by avoiding the use of ODB transactions in `index_fd()` when
callers are only interested in computing the object hash.

Reported-by: Luca Stefani <luca.stefani.ge1@gmail.com>
Signed-off-by: Justin Tobler <jltobler@gmail.com>
[jc: adjusted to fd13909e (Merge branch 'jt/odb-transaction', 2025-10-02)]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoA bit more before -rc1
Junio C Hamano [Tue, 7 Apr 2026 21:59:08 +0000 (14:59 -0700)] 
A bit more before -rc1

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'rs/history-short-help-fix'
Junio C Hamano [Tue, 7 Apr 2026 21:59:28 +0000 (14:59 -0700)] 
Merge branch 'rs/history-short-help-fix'

Glitches in "git history -h" have been corrected.

* rs/history-short-help-fix:
  history: fix short help for argument of --update-refs

2 months agoMerge branch 'th/backfill-auto-detect-sparseness-fix'
Junio C Hamano [Tue, 7 Apr 2026 21:59:28 +0000 (14:59 -0700)] 
Merge branch 'th/backfill-auto-detect-sparseness-fix'

"git backfill" is capable of auto-detecting a sparsely checked out
working tree, which was broken.

* th/backfill-auto-detect-sparseness-fix:
  backfill: auto-detect sparse-checkout from config

2 months agoMerge branch 'ps/receive-pack-updateinstead-in-worktree'
Junio C Hamano [Tue, 7 Apr 2026 21:59:27 +0000 (14:59 -0700)] 
Merge branch 'ps/receive-pack-updateinstead-in-worktree'

The check in "receive-pack" to prevent a checked out branch from
getting updated via updateInstead mechanism has been corrected.

* ps/receive-pack-updateinstead-in-worktree:
  receive-pack: use worktree HEAD for updateInstead
  t5516: clean up cloned and new-wt in denyCurrentBranch and worktrees test
  t5516: test updateInstead with worktree and unborn bare HEAD

2 months agoMerge branch 'jt/fast-import-signed-modes'
Junio C Hamano [Tue, 7 Apr 2026 21:59:27 +0000 (14:59 -0700)] 
Merge branch 'jt/fast-import-signed-modes'

Handling of signed commits and tags in fast-import has been made more
configurable.

* jt/fast-import-signed-modes:
  fast-import: add 'abort-if-invalid' mode to '--signed-tags=<mode>'
  fast-import: add 'sign-if-invalid' mode to '--signed-tags=<mode>'
  fast-import: add 'strip-if-invalid' mode to '--signed-tags=<mode>'
  fast-import: add 'abort-if-invalid' mode to '--signed-commits=<mode>'
  fast-export: check for unsupported signing modes earlier

2 months agoMerge branch 'mm/line-log-use-standard-diff-output'
Junio C Hamano [Tue, 7 Apr 2026 21:59:27 +0000 (14:59 -0700)] 
Merge branch 'mm/line-log-use-standard-diff-output'

The way the "git log -L<range>:<file>" feature is bolted onto the
log/diff machinery is being reworked a bit to make the feature
compatible with more diff options, like -S/G.

* mm/line-log-use-standard-diff-output:
  doc: note that -L supports patch formatting and pickaxe options
  t4211: add tests for -L with standard diff options
  line-log: route -L output through the standard diff pipeline
  line-log: fix crash when combined with pickaxe options

2 months agoMerge branch 'sp/add-patch-with-fewer-the-repository'
Junio C Hamano [Tue, 7 Apr 2026 21:59:26 +0000 (14:59 -0700)] 
Merge branch 'sp/add-patch-with-fewer-the-repository'

Reduce dependency on `the_repository` in add-patch.c file.

* sp/add-patch-with-fewer-the-repository:
  add-patch: use repository instance from add_i_state instead of the_repository

2 months agoMerge branch 'ps/fsck-wo-the-repository'
Junio C Hamano [Tue, 7 Apr 2026 21:59:26 +0000 (14:59 -0700)] 
Merge branch 'ps/fsck-wo-the-repository'

Internals of "git fsck" have been refactored to not depend on the
global `the_repository` variable.

* ps/fsck-wo-the-repository:
  builtin/fsck: stop using `the_repository` in error reporting
  builtin/fsck: stop using `the_repository` when marking objects
  builtin/fsck: stop using `the_repository` when checking packed objects
  builtin/fsck: stop using `the_repository` with loose objects
  builtin/fsck: stop using `the_repository` when checking reflogs
  builtin/fsck: stop using `the_repository` when checking refs
  builtin/fsck: stop using `the_repository` when snapshotting refs
  builtin/fsck: fix trivial dependence on `the_repository`
  fsck: drop USE_THE_REPOSITORY
  fsck: store repository in fsck options
  fsck: initialize fsck options via a function
  fetch-pack: move fsck options into function scope

2 months agoMerge branch 'yc/path-walk-fix-error-reporting'
Junio C Hamano [Tue, 7 Apr 2026 21:59:26 +0000 (14:59 -0700)] 
Merge branch 'yc/path-walk-fix-error-reporting'

The value of a wrong pointer variable was referenced in an error
message that reported that it shouldn't be NULL.

* yc/path-walk-fix-error-reporting:
  path-walk: fix NULL pointer dereference in error message

2 months agoMerge branch 'jc/whitespace-incomplete-line'
Junio C Hamano [Tue, 7 Apr 2026 21:59:26 +0000 (14:59 -0700)] 
Merge branch 'jc/whitespace-incomplete-line'

Fix whitespace correction for new-style empty context lines.

* jc/whitespace-incomplete-line:
  apply: fix new-style empty context line triggering incomplete-line check

2 months agoMerge branch 'ps/commit-graph-overflow-fix'
Junio C Hamano [Tue, 7 Apr 2026 21:59:25 +0000 (14:59 -0700)] 
Merge branch 'ps/commit-graph-overflow-fix'

Fix a regression in writing the commit-graph where commits with dates
exceeding 34 bits (beyond year 2514) could cause an underflow and
crash Git during the generation data overflow chunk writing.

* ps/commit-graph-overflow-fix:
  commit-graph: fix writing generations with dates exceeding 34 bits

2 months agoMerge branch 'jd/read-cache-trace-wo-the-repository'
Junio C Hamano [Tue, 7 Apr 2026 21:59:25 +0000 (14:59 -0700)] 
Merge branch 'jd/read-cache-trace-wo-the-repository'

A handful of inappropriate uses of the_repository have been
rewritten to use the right repository structure instance in the
read-cache.c codepath.

* jd/read-cache-trace-wo-the-repository:
  read-cache: use istate->repo for trace2 logging

2 months agot5710: use proper file:// URIs for absolute paths
Christian Couder [Tue, 7 Apr 2026 11:52:43 +0000 (13:52 +0200)] 
t5710: use proper file:// URIs for absolute paths

In t5710, we frequently construct local file URIs using `file://$(pwd)`.
On Unix-like systems, $(pwd) returns an absolute path starting with a
slash (e.g., `/tmp/repo`), resulting in a valid 3-slash URI with an
empty host (`file:///tmp/repo`).

However, on Windows, $(pwd) returns a path starting with a drive
letter (e.g., `D:/a/repo`). This results in a 2-slash URI
(`file://D:/a/repo`). Standard URI parsers misinterpret this format,
treating `D:` as the host rather than part of the absolute path.

This is to be expected because RFC 8089 says that the `//` prefix with
an empty local host must be followed by an absolute path starting with
a slash.

While this hasn't broken the existing tests (because the old
`promisor.acceptFromServer` logic relies entirely on strict `strcmp()`
without normalizing the URLs), it will break future commits that pass
these URLs through `url_normalize()` or similar functions.

To future-proof the tests and ensure cross-platform URI compliance,
let's introduce a $TRASH_DIRECTORY_URL helper variable that explicitly
guarantees a leading slash for the path component, ensuring valid
3-slash `file:///` URIs on all operating systems.

While at it, let's also introduce $ENCODED_TRASH_DIRECTORY_URL to
handle some common special characters in directory paths.

To be extra safe, let's skip all the tests if there are uncommon
special characters in the directory path.

Then let's replace all instances of `file://$(pwd)` with
$TRASH_DIRECTORY_URL across the test script, and let's simplify the
`sendFields` and `checkFields` tests to use
$ENCODED_TRASH_DIRECTORY_URL directly.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: remove the 'accepted' strvec
Christian Couder [Tue, 7 Apr 2026 11:52:42 +0000 (13:52 +0200)] 
promisor-remote: remove the 'accepted' strvec

In a previous commit, filter_promisor_remote() was refactored to keep
accepted 'struct promisor_info' instances alive instead of dismantling
them into separate parallel data structures.

Let's go one step further and replace the 'struct strvec *accepted'
argument passed to filter_promisor_remote() with a
'struct string_list *accepted_remotes' argument.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: keep accepted promisor_info structs alive
Christian Couder [Tue, 7 Apr 2026 11:52:41 +0000 (13:52 +0200)] 
promisor-remote: keep accepted promisor_info structs alive

In filter_promisor_remote(), the instances of `struct promisor_info`
for accepted remotes are dismantled into separate parallel data
structures (the 'accepted' strvec for server names, and
'accepted_filters' for filter strings) and then immediately freed.

Instead, let's keep these instances on an 'accepted_remotes' list.

This way the post-loop phase can iterate a single list to build the
protocol reply, apply advertised filters, and mark remotes as
accepted, rather than iterating three separate structures.

This refactoring also prepares for a future commit that will add a
'local_name' member to 'struct promisor_info'. Since struct instances
stay alive, downstream code will be able to simply read both names
from them rather than needing yet another parallel strvec.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: refactor accept_from_server()
Christian Couder [Tue, 7 Apr 2026 11:52:40 +0000 (13:52 +0200)] 
promisor-remote: refactor accept_from_server()

In future commits, we are going to add more logic to
filter_promisor_remote() which is already doing a lot of things.

Let's alleviate that by moving the logic that checks and validates the
value of the `promisor.acceptFromServer` config variable into its own
accept_from_server() helper function.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: refactor has_control_char()
Christian Couder [Tue, 7 Apr 2026 11:52:39 +0000 (13:52 +0200)] 
promisor-remote: refactor has_control_char()

In a future commit we are going to check if some strings contain
control characters, so let's refactor the logic to do that in a new
has_control_char() helper function.

It cleans up the code a bit anyway.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: refactor should_accept_remote() control flow
Christian Couder [Tue, 7 Apr 2026 11:52:38 +0000 (13:52 +0200)] 
promisor-remote: refactor should_accept_remote() control flow

A previous commit made sure we now reject empty URLs early at parse
time. This makes the existing warning() in case a remote URL is NULL
or empty very unlikely to be useful.

In future work, we also plan to add URL-based acceptance logic into
should_accept_remote().

To adapt to previous changes and prepare for upcoming changes, let's
restructure the control flow in should_accept_remote().

Concretely, let's:

 - Replace the warning() in case of an empty URL with a BUG(), as a
   previous commit made sure empty URLs are rejected early at parse
   time.

 - Move that modified empty-URL check to the very top of the function,
   so that every acceptance mode, instead of only ACCEPT_KNOWN_URL, is
   covered.

 - Invert the URL comparison: instead of returning on match and
   warning on mismatch, return early on mismatch and let the match
   case fall through. This opens a single exit path at the bottom of
   the function for future commits to extend.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: reject empty name or URL in advertised remote
Christian Couder [Tue, 7 Apr 2026 11:52:37 +0000 (13:52 +0200)] 
promisor-remote: reject empty name or URL in advertised remote

In parse_one_advertised_remote(), we check for a NULL remote name and
remote URL, but not for empty ones. An empty URL seems possible as
url_percent_decode("") doesn't return NULL.

In promisor_config_info_list(), we ignore remotes with empty URLs, so a
Git server should not advertise remotes with empty URLs. It's possible
that a buggy or malicious server would do it though.

So let's tighten the check in parse_one_advertised_remote() to also
reject empty strings at parse time.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: clarify that a remote is ignored
Christian Couder [Tue, 7 Apr 2026 11:52:36 +0000 (13:52 +0200)] 
promisor-remote: clarify that a remote is ignored

In should_accept_remote() and parse_one_advertised_remote(), when a
remote is ignored, we tell users why it is ignored in a warning, but we
don't tell them that the remote is actually ignored.

Let's clarify that, so users have a better idea of what's actually
happening.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: pass config entry to all_fields_match() directly
Christian Couder [Tue, 7 Apr 2026 11:52:35 +0000 (13:52 +0200)] 
promisor-remote: pass config entry to all_fields_match() directly

The `in_list == 0` path of all_fields_match() looks up the remote in
`config_info` by `advertised->name` repeatedly, even though every
caller in should_accept_remote() has already performed this
lookup and holds the result in `p`.

To avoid this useless work, let's replace the `int in_list`
parameter with a `struct promisor_info *config_entry` pointer:

 - When NULL (ACCEPT_ALL mode): scan the whole `config_info` list, as
   the old `in_list == 1` path did.

 - When non-NULL: match against that single config entry directly,
   avoiding the redundant string_list_lookup() call.

This removes the hidden dependency on `advertised->name` inside
all_fields_match(), which would be wrong if in the future
auto-configured remotes are implemented, as the local config name may
differ from the server's advertised name.

While at it, let's also add a comment before all_fields_match() and
match_field_against_config() to help understand how things work and
help avoid similar issues.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopromisor-remote: try accepted remotes before others in get_direct()
Christian Couder [Tue, 7 Apr 2026 11:52:34 +0000 (13:52 +0200)] 
promisor-remote: try accepted remotes before others in get_direct()

When a server advertises promisor remotes and the client accepts some
of them, those remotes carry the server's intent: 'fetch missing
objects preferably from here', and the client agrees with that for the
remotes it accepts.

However promisor_remote_get_direct() actually iterates over all
promisor remotes in list order, which is the order they appear in the
config files (except perhaps for the one appearing in the
`extensions.partialClone` config variable which is tried last).

This means an existing, but not accepted, promisor remote, could be
tried before the accepted ones, which does not reflect the intent of
the agreement between client and server.

If the client doesn't care about what the server suggests, it should
accept nothing and rely on its remotes as they are already configured.

To better reflect the agreement between client and server, let's make
promisor_remote_get_direct() try the accepted promisor remotes before
the non-accepted ones.

Concretely, let's extract a try_promisor_remotes() helper and call it
twice from promisor_remote_get_direct():

- first with an `accepted_only=true` argument to try only the accepted
  remotes,
- then with `accepted_only=false` to fall back to any remaining remote.

Ensuring that accepted remotes are preferred will be even more
important if in the future a mechanism is developed to allow the
client to auto-configure remotes that the server advertises. This will
in particular avoid fetching from the server (which is already
configured as a promisor remote) before trying the auto-configured
remotes, as these new remotes would likely appear at the end of the
config file, and as the server might not appear in the
`extensions.partialClone` config variable.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'aa/reap-transport-child-processes'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'aa/reap-transport-child-processes'

A few code paths that spawned child processes for network
connection weren't wait(2)ing for their children and letting "init"
reap them instead; they have been tightened.

* aa/reap-transport-child-processes:
  transport-helper, connect: use clean_on_exit to reap children on abnormal exit

2 months agoA handful before -rc1
Junio C Hamano [Mon, 6 Apr 2026 22:42:30 +0000 (15:42 -0700)] 
A handful before -rc1

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'jk/c23-const-preserving-fixes'
Junio C Hamano [Mon, 6 Apr 2026 22:42:51 +0000 (15:42 -0700)] 
Merge branch 'jk/c23-const-preserving-fixes'

Adjust the codebase for C23 that changes functions like strchr()
that discarded constness when they return a pointer into a const
string to preserve constness.

* jk/c23-const-preserving-fixes:
  config: store allocated string in non-const pointer
  rev-parse: avoid writing to const string for parent marks
  revision: avoid writing to const string for parent marks
  rev-parse: simplify dotdot parsing
  revision: make handle_dotdot() interface less confusing

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 agopromisor-remote: fix promisor.quiet to use the correct repository
Trieu Huynh [Mon, 6 Apr 2026 18:30:41 +0000 (03:30 +0900)] 
promisor-remote: fix promisor.quiet to use the correct repository

fetch_objects() reads the promisor.quiet configuration from
the_repository instead of the repo parameter it receives.

This means that when git lazy-fetches objects for a non-main
repository, eg. a submodule that is itself a partial clone opened
via repo_submodule_init(). The submodule's own promisor.quiet
setting is ignored and the superproject's setting is used instead.

Fix by replacing the_repository with repo in the repo_config_get_bool()
call. The practical trigger is git grep --recurse-submodules on a
superproject where the submodule is a partial clone.

Add a test where promisor.quiet is set only in a partial-clone
submodule; a lazy fetch triggered by "git grep --recurse-submodules"
must honor that setting.

Signed-off-by: Trieu Huynh <vikingtc4@gmail.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>