win32: ensure that `localtime_r()` is declared even in i686 builds
The `__MINGW64__` constant is defined, surprise, surprise, only when
building for a 64-bit CPU architecture.
Therefore using it as a guard to define `_POSIX_C_SOURCE` (so that
`localtime_r()` is declared, among other functions) is not enough, we
also need to check `__MINGW32__`.
Technically, the latter constant is defined even for 64-bit builds. But
let's make things a bit easier to understand by testing for both
constants.
Making it so fixes this compile warning (turned error in GCC v14.1):
archive-zip.c: In function 'dos_time':
archive-zip.c:612:9: error: implicit declaration of function 'localtime_r';
did you mean 'localtime_s'? [-Wimplicit-function-declaration]
612 | localtime_r(&time, &tm);
| ^~~~~~~~~~~
| localtime_s
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* js/objects-larger-than-4gb-on-windows-more:
odb: use size_t for object_info.sizep and the size APIs
packfile,delta: drop the `cast_size_t_to_ulong()` wrappers
pack-objects: use size_t for in-core object sizes
packfile: widen unpack_entry()'s size out-parameter to size_t
pack-objects(check_pack_inflate()): use size_t instead of unsigned long
patch-delta: use size_t for sizes
compat/msvc: use _chsize_s for ftruncate
Some link recipes list the same archive twice, which is harmless.
Quiet the warning instead.
Pass -Wl,-no_warn_duplicate_libraries on Xcode 15 and newer, whose
linkers added both the warning and the suppression flag (ld64-907
and dyld-1009). Earlier linkers reject the flag, so gate on the
linker version. Broaden the existing -fno-common version probe to
also match the "ld64-NNN" and "dyld-NNN" forms Xcode 15 reports.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
On platforms where `unsigned long` and `size_t` differ in bit size, we
want to clamp the buffers we pass to zlib to the former's size, as per d05d666977 (git-zlib: handle data streams larger than 4GB, 2026-05-08).
The logic introduced in that commit performs a clamping to the bits,
though, which fails to do what is needed here: If too many bytes are
available in the buffers, we need to clamp to the maximum value of an
`unsigned long`. Otherwise, we ask zlib to use too small buffers, in the
worst case using 0 as the size (think: a value whose 32 lowest bits are
all zero).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
gitlab-ci: migrate Windows builds away from Chocolatey
The Windows builds in GitLab CI use Chocolatey to install dependencies.
Unfortunately, Chocolatey seems to be very unreliable, which causes the
jobs to fail very regularly. This is a limitation that seems to be
somewhat known [1]:
As an organization, you want 100% reliability (or at least that
potential), and you may want full trust and control as well. This is
something you can get with internally hosted packages, and you are
unlikely to achieve from use of the Community Package Repository.
So using the Community Package Repository is kind of discouraged in case
one wants reliability. We _do_ want reliability though, and we cannot
easily switch to an enterprise license to fix this issue.
Introduce a new script that downloads and installs dependencies
directly. This has a couple of benefits:
- We can drop our dependency on Chocolatey completely, thus improving
reliability.
- We can easily cache the installers.
- We get direct control over the exact versions we install.
- Installing dependencies is sped up from roundabout 3 minutes to 1
minute.
Junio C Hamano [Wed, 17 Jun 2026 18:10:12 +0000 (11:10 -0700)]
Merge branch 'en/commit-graph-timestamp-fix'
compute_reachable_generation_numbers() in commit-graph used a 32-bit
integer to accumulate parent generations, which is OK for generation
number v1 (topological levels), but with generation number v2
(adjusted committer timestamps), it truncated timestamps beyond
2106. Fixed by widening the accumulator to timestamp_t.
* en/commit-graph-timestamp-fix:
commit-graph: use timestamp_t for max parent generation accumulator
Junio C Hamano [Wed, 17 Jun 2026 18:10:12 +0000 (11:10 -0700)]
Merge branch 'dl/posix-unused-warning-clang'
The UNUSED macro in 'compat/posix.h' has been updated to use a
newly introduced GIT_CLANG_PREREQ macro for compiler version
checks, and the existing GIT_GNUC_PREREQ macro has been modernized
to use explicit major/minor comparisons rather than bit-shifting.
* dl/posix-unused-warning-clang:
compat/posix.h: simplify GIT_GNUC_PREREQ() comparison
compat/posix.h: clean up GIT_GNUC_PREREQ() and UNUSED
compat/posix.h: enable UNUSED warning messages for Clang
Junio C Hamano [Wed, 17 Jun 2026 18:10:11 +0000 (11:10 -0700)]
Merge branch 'td/ls-files-pathspec-prefilter'
`git ls-files --modified` and `git ls-files --deleted` have been
optimized to filter with pathspec before calling lstat() when there is
only a single pathspec item, avoiding unnecessary filesystem access
for entries that will not be shown.
* td/ls-files-pathspec-prefilter:
ls-files: filter pathspec before lstat
Junio C Hamano [Wed, 17 Jun 2026 18:10:11 +0000 (11:10 -0700)]
Merge branch 'td/describe-tag-iteration'
'git describe' has been taught to pass the 'refs/tags/' prefix down to
the ref iterator when '--all' is not requested, avoiding unnecessary
iteration over non-tag refs.
* td/describe-tag-iteration:
describe: limit default ref iteration to tags
Junio C Hamano [Wed, 17 Jun 2026 18:10:11 +0000 (11:10 -0700)]
Merge branch 'ps/transport-helper-tsan-fix'
The TSAN race in transfer_debug() within transport-helper.c has been
resolved by initializing the debug flag early in
bidirectional_transfer_loop() before spawning worker threads, allowing
the removal of a TSAN suppression.
* ps/transport-helper-tsan-fix:
transport-helper: fix TSAN race in transfer_debug()
Junio C Hamano [Wed, 17 Jun 2026 12:39:13 +0000 (05:39 -0700)]
Merge branch 'ab/index-pack-retain-child-bases'
"git index-pack" has been optimized by retaining child bases in the
delta cache instead of immediately freeing them, letting the existing
cache limit policy decide eviction.
* ab/index-pack-retain-child-bases:
index-pack: retain child bases in delta cache
Without NO_RUST defined, the varint encoder/decoder lives in the
RUST_LIB, which needs to be linked. Symptom:
cc [... -o contrib/credential/osxkeychain/git-credential-osxkeychain [...]
Undefined symbols for architecture x86_64:
"_decode_varint", referenced from:
_read_untracked_extension in libgit.a[x86_64][63](dir.o)
_read_untracked_extension in libgit.a[x86_64][63](dir.o)
_read_one_dir in libgit.a[x86_64][63](dir.o)
_read_one_dir in libgit.a[x86_64][63](dir.o)
_load_cache_entry_block in libgit.a[x86_64][174](read-cache.o)
"_encode_varint", referenced from:
_write_untracked_extension in libgit.a[x86_64][63](dir.o)
_write_untracked_extension in libgit.a[x86_64][63](dir.o)
_write_untracked_extension in libgit.a[x86_64][63](dir.o)
_write_one_dir in libgit.a[x86_64][63](dir.o)
_write_one_dir in libgit.a[x86_64][63](dir.o)
_do_write_index in libgit.a[x86_64][174](read-cache.o)
ld: symbol(s) not found for architecture x86_64
While it is curious why these functions are needed at all (osxkeychain
does not read or write the index), the compile error is a real problem.
Instead of trying to play games to add `GITLIBS` while filtering out
`common-main.o`, replace the `$(LIB_FILE) $(EXTLIBS)` construct with the
much shorter `$(LIBS)` construct that _already_ filters out
`common-main.o` and adds the Rust library when needed.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano [Tue, 16 Jun 2026 16:01:03 +0000 (09:01 -0700)]
Merge branch 'mm/subprocess-handshake-fix'
The subprocess handshake during startup has been made gentler by using
packet_read_line_gently() instead of packet_read_line() to prevent the
parent Git process from dying abruptly when a configured subprocess
(e.g., a clean/smudge filter) fails to start.
* mm/subprocess-handshake-fix:
sub-process: use gentle handshake to avoid die() on startup failure
Junio C Hamano [Tue, 16 Jun 2026 16:01:02 +0000 (09:01 -0700)]
Merge branch 'ps/t7527-fix-tap-output'
A recent regression in t7527 that broke TAP output has been fixed,
some other test noise that also broke TAP output has been silenced,
and 'prove' is now configured to fail on invalid TAP output to
prevent future regressions.
* ps/t7527-fix-tap-output:
t: let prove fail when parsing invalid TAP output
t/lib-git-p4: silence output when killing p4d and its watchdog
t/test-lib: silence EBUSY errors on Windows during test cleanup
t7810: turn MB_REGEX check into a lazy prereq
t7527: fix broken TAP output
ci: unify Linux images across GitLab and GitHub
gitlab-ci: add missing Linux jobs
gitlab-ci: rearrange Linux jobs to match GitHub's order
Junio C Hamano [Tue, 16 Jun 2026 16:01:02 +0000 (09:01 -0700)]
Merge branch 'jk/describe-contains-all-match-fix'
The 'git describe --contains --all' command has been fixed to
properly honor the '--match' and '--exclude' options by passing
them down to 'git name-rev' with the appropriate reference
prefixes.
* jk/describe-contains-all-match-fix:
describe: fix --exclude, --match with --contains and --all
Junio C Hamano [Tue, 16 Jun 2026 16:01:02 +0000 (09:01 -0700)]
Merge branch 'mf/revision-max-count-oldest'
"git rev-list" (and "git log" family of commands) learned a new "--max-count-oldest"
that picks oldest N commits in the range instead of the usual newest.
Junio C Hamano [Tue, 16 Jun 2026 16:01:02 +0000 (09:01 -0700)]
Merge branch 'js/win-kill-child-more-gently'
Advanced emulation of kill() used on Windows in GfW has been
upstreamed to improve the symptoms like left-behind .lock files and
that fails to let the child clean-up itself when it gets killed.
* js/win-kill-child-more-gently:
mingw: really handle SIGINT
mingw: kill child processes in a gentler way
odb: use size_t for object_info.sizep and the size APIs
When `js/objects-larger-than-4gb-on-windows` widened the streaming,
index-pack and unpack-objects code paths, in the interest of keeping the
patches somewhat reasonably-sized, it left the public ODB API still
typed in `unsigned long`. In particular `struct object_info::sizep` and
the four wrappers built on top of it (`odb_read_object`,
`odb_read_object_peeled`, `odb_read_object_info`, `odb_pretend_object`)
still return the unpacked size through `unsigned long *`, so on Windows
`cat-file -s` and the `git add` / `git status` paths for a >4 GiB blob
silently cap at 4 GiB.
Widen the field and the four wrappers. The previous commits already
widened the `unpack_entry()` cascade and pack-objects' in-core size
accessors, so most of the cascade arrives here with no further work: the
temporary shims in `packed_object_info_with_index_pos()` and in
`unpack_entry()`'s delta-base recovery path go away, the two
`SET_SIZE(entry, cast_size_t_to_ulong(canonical_size))` calls in
`check_object()` and the matching one in `drop_reused_delta()` collapse
to plain `SET_SIZE`, and `oe_get_size_slow()`'s tail
`cast_size_t_to_ulong()` is gone too.
What remains narrow are the boundaries this series does not
intend to touch: the diff, blame, textconv and fast-import machinery.
Even so, this patch is unfortunately quite large.
Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
packfile,delta: drop the `cast_size_t_to_ulong()` wrappers
When I started the transition from `unsigned long` to `size_t`, in the
interest of keeping the patches reviewable, I introduced these calls to
prevent data type narrowing from silently failing to handle large object
sizes. I also introduced `*_sz()` variants that would allow most of the
callers to keep using that `unsigned long` that the 90s kindly asked to
be returned.
After the preceding commits, the only places that called the narrow
wrappers either no longer exist or already use the `_sz` form
internally, so the wrappers just narrow values back through
`cast_size_t_to_ulong()` for no reason.
Drop them and rename the `_sz` variants back to the natural names.
Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
`pack-objects` stores per-entry object sizes in either the 31-bit
`size_` member of the `struct object_entry` or, when the value does not
fit, the `pack->delta_size[]` spill array. The accessors (`oe_size`,
`oe_delta_size`, `oe_get_size_slow`, `oe_size_*_than`) and the setters
(`oe_set_size`, `oe_set_delta_size`) used `unsigned long` for the spill
type, which on Windows means the spill silently caps at 4 GiB per entry.
That is what made `upload-pack` die with "object too large to read on
this platform" when serving the >4 GiB blob in `t5608` tests 5 and 6
when run with `GIT_TEST_CLONE_2GB`.
Widen them all to `size_t` (including `pack->delta_size`) and drop the
three `cast_size_t_to_ulong()` calls in `check_object()` that guarded
`in_pack_size`. The two `SET_SIZE(entry, canonical_size)` calls in the
same function stay cast-free as before, since `canonical_size` is still
`unsigned long` until a later commit widens `object_info::sizep`.
Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
packfile: widen unpack_entry()'s size out-parameter to size_t
The topic `js/objects-larger-than-4gb-on-windows` widened the streaming,
index-pack and unpack-objects paths to `size_t` but deliberately stopped
at the in-memory `unpack_entry()` cascade, which still hands back the
unpacked size through `unsigned long *`. On Windows that boundary
truncates above 4 GiB because that data type is only 32 bits wide on
that platform.
Widen the code path. Except `packed_object_info_with_index_pos()`: It
cannot yet pass `oi->sizep` directly because the field is still
`unsigned long *`; bridge it with a `size_t` temporary that narrows
back, and let a later commit drop the bridge once the field is wide
too. `gfi_unpack_entry()` keeps its narrow signature because fast-import
tracks sizes through `unsigned long` everywhere it crosses subsystem
boundaries, keeping its signature allows the scope of this commit to be
somewhat reasonable, still.
Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
pack-objects(check_pack_inflate()): use size_t instead of unsigned long
`write_reuse_object()` learned to track its packed-object size as
`size_t` in 606c192380 (odb, packfile: use size_t for streaming
object sizes, 2026-05-08), but the comparison sink it feeds,
`check_pack_inflate()`, still takes the expected decompressed size
as `unsigned long`. The call site bridges the mismatch with
`cast_size_t_to_ulong()`, which on Windows turns a >4 GiB object
into an immediate die().
That function only uses `expect` once: as the right-hand side of a
`stream.total_out == expect` equality test against zlib's counter.
zlib's own `total_out` counter is `uLong` and is therefore still
32-bit-bound on Windows. Widening `expect` to `size_t` cannot fix that,
but it is a strict improvement nonetheless: instead of dying outright,
an oversized object now simply makes the equality fail and lets
`write_reuse_object()` fall back to `write_no_reuse_object()`, which
decompresses and re-deflates the content (and which the larger
pack-objects widening series targets separately).
Drop the `cast_size_t_to_ulong()` shim at the call site now that
the receiving parameter speaks the same type as `entry_size`.
Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
`patch_delta()` takes the source and delta sizes by value and writes
back the reconstructed target size through an `unsigned long *`. That
datatype cannot represent a value that exceeds 4 GiB on systems where
`unsigned long` is 32-bit (notably 64-bit Windows builds), though, even
though the delta encoding itself, the on-disk layout, and the in-memory
buffers happily carry such sizes. A `size_t` companion to
`get_delta_hdr_size()`, `get_delta_hdr_size_sz()`, was introduced in 17fa077596 (delta, packfile: use size_t for delta header sizes,
2026-05-08) precisely so that `patch_delta()` could be widened without
changing the on-the-wire decoding helper's signature.
Widen `patch_delta()`'s three size parameters to `size_t` and switch
its internal use of `get_delta_hdr_size()` to the `_sz` variant.
Then propagate the wider type through the callers.
Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
On Windows, `unsigned long` and `long` are 32 bits even on 64-bit
builds. The MSVC compatibility header has shimmed `ftruncate()` with
#define ftruncate _chsize
ever since `compat/msvc-posix.h` was introduced. `_chsize()` takes a
32-bit `long` for the new length, which silently truncates files (and
the requested size) to 2 GiB. That is enough to make t7508 test 126
"git add fails gracefully with 4 GiB and 8 GiB files" fail under
MSVC: `test-tool truncate` creates a sparse 4 GiB or 8 GiB file via
the shimmed `ftruncate()`, and the test never gets off the ground.
`_chsize_s()` is the modern replacement, accepts a 64-bit `__int64`
length, and is the only sensible target on Windows. The catch is that
it does not follow the POSIX `-1` + `errno` convention: it returns
`0` on success and an errno value (a small positive integer) on
failure. A plain `#define ftruncate _chsize_s` would therefore
silently break callers that test the return value as `< 0` or against
`-1`, of which there are several: `http.c`, `parallel-checkout.c`,
and `t/helper/test-truncate.c` among them.
Introduce a `static inline` wrapper that calls `_chsize_s()`, copies
its errno return into `errno`, and translates the result to the
familiar `-1` / `0` convention, then point `ftruncate` at the
wrapper. Place the wrapper after `#include "mingw-posix.h"` so the
`off_t` parameter resolves to the already-widened `off64_t` rather
than the 32-bit `_off_t` from `compat/vcbuild/include/unistd.h`.
MinGW is unaffected: its `ftruncate()` already takes `off_t` and
routes through `ftruncate64()` when `_FILE_OFFSET_BITS=64`, which is
the default in our build.
Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano [Mon, 15 Jun 2026 14:42:00 +0000 (07:42 -0700)]
Merge branch 'ob/more-repo-config-values'
Many core configuration variables have been migrated from global
variables into 'repo_config_values' to tie them to a specific
repository instance, avoiding cross-repository state leakage.
* ob/more-repo-config-values:
environment: move "warn_on_object_refname_ambiguity" into `struct repo_config_values`
environment: move "sparse_expect_files_outside_of_patterns" into `struct repo_config_values`
environment: move "core_sparse_checkout_cone" into `struct repo_config_values`
environment: move "precomposed_unicode" into `struct repo_config_values`
environment: move "pack_compression_level" into `struct repo_config_values`
environment: move `zlib_compression_level` into `struct repo_config_values`
environment: move "check_stat" into `struct repo_config_values`
environment: move "trust_ctime" into `struct repo_config_values`
Junio C Hamano [Mon, 15 Jun 2026 14:41:59 +0000 (07:41 -0700)]
Merge branch 'ps/setup-centralize-odb-creation'
The setup logic to discover and configure repositories has been
refactored, and the initialization of the object database has been
centralized.
* ps/setup-centralize-odb-creation:
setup: construct object database in `apply_repository_format()`
repository: stop reading loose object map twice on repo init
setup: stop initializing object database without repository
setup: stop creating the object database in `setup_git_env()`
repository: stop initializing the object database in `repo_set_gitdir()`
setup: deduplicate logic to apply repository format
setup: drop `setup_git_env()`
t0001: plug test gaps for git-init(1) with GIT_OBJECT_DIRECTORY
Junio C Hamano [Mon, 15 Jun 2026 14:41:59 +0000 (07:41 -0700)]
Merge branch 'hn/config-typo-advice'
"git config foo.bar=baz" is not likely to be a request to read the
value of such a variable with '=' in its name; rather it is plausible
that the user meant "git config set foo.bar baz". Give advice when
giving an error message.
* hn/config-typo-advice:
config: improve diagnostic for "set" with missing value
config: add git_config_key_is_valid() for quiet validation
Junio C Hamano [Mon, 15 Jun 2026 14:41:59 +0000 (07:41 -0700)]
Merge branch 'ls/doc-raw-timestamp-prefix'
Documentation and tests have been added to clarify that Git's internal
raw timestamp format requires a `@` prefix for values less than
100,000,000 to prevent ambiguity with other formats like YYYYMMDD.
* ls/doc-raw-timestamp-prefix:
doc: document and test `@` prefix for raw timestamps
Junio C Hamano [Mon, 15 Jun 2026 14:41:59 +0000 (07:41 -0700)]
Merge branch 'jc/submitting-patches-cover-letter'
Guidelines on how to write a cover letter for a multi-patch series
have been added to SubmittingPatches, which also got a new marker
to separate the section for typofixes.
* jc/submitting-patches-cover-letter:
SubmittingPatches: describe cover letter
SubmittingPatches: separate typofixes section
Elijah Newren [Sun, 14 Jun 2026 06:57:50 +0000 (06:57 +0000)]
commit-graph: use timestamp_t for max parent generation accumulator
compute_reachable_generation_numbers() computes each commit's
generation as
max(c->date, max(parent.generation)) + 1
by walking its parents and accumulating their generations into a
local
uint32_t max_gen = 0;
while info->get_generation() returns timestamp_t and
compute_generation_from_max() already takes its max_gen parameter
as timestamp_t. For v1 (topological levels) the narrowing is
harmless because GENERATION_NUMBER_V1_MAX is less than 2^30, but
for v2 (corrected committer dates) it silently truncates any
parent generation that does not fit in 32 bits, i.e. any parent
whose committer timestamp is at or beyond 2106-02-07 UTC
(>= 2^32).
The truncated max then causes child commits to end up with a
corrected committer date that matches the parent's instead of being
at least 1 higher. The bad value gets written into the commit-graph
and causes problems later, and can be noticed by running `git
commit-graph verify`.
Widen the accumulator to timestamp_t.
This is solely an in-memory arithmetic fix with no on-disk format
change: the on-disk format already encodes timestamp_t values and
existing readers handle them unchanged. This merely allows the code to
compute the correct value to write to disk.
The narrowing was introduced in 80c928d947c2 (commit-graph:
simplify compute_generation_numbers(), 2023-03-20), which rewired
v2 to use the shared compute_reachable_generation_numbers()
helper; the helper's local accumulator had been declared uint32_t
in the immediately preceding 368d19b0b7fa (commit-graph: refactor
compute_topological_levels(), 2023-03-20) when only v1 was using
it, where it was harmless.
Add a new test with a future-dated parent and a present-day child;
without the above fix, `git commit-graph verify` reports the
descendant's stored generation as below parent + 1.
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Dominik Loidolt [Sat, 13 Jun 2026 12:27:09 +0000 (14:27 +0200)]
compat/posix.h: enable UNUSED warning messages for Clang
Use a dedicated Clang version check for the UNUSED macro.
Commit 7c07f36ad2 (git-compat-util.h: GCC deprecated message arg only in
GCC 4.5+, 2022-10-05) restricted use of the deprecated attribute's
message argument in the UNUSED macro to GCC 4.5 or newer.
Clang identifies itself as GNUC 4.2.1 for compatibility, so
GIT_GNUC_PREREQ(4, 5) does not detect whether Clang supports the
deprecated("...") form. Add GIT_CLANG_PREREQ() macro and use it to
enable the UNUSED warning message for Clang 2.9 and newer.
Signed-off-by: Dominik Loidolt <dominik.loidolt@univie.ac.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Tamir Duberstein [Fri, 12 Jun 2026 04:31:51 +0000 (21:31 -0700)]
ls-files: filter pathspec before lstat
In --deleted and --modified modes, show_files() calls lstat() for each
index entry before show_ce() applies the pathspec. prune_index() avoids
most of these calls for pathspecs with a common directory prefix, but
not for a top-level name or leading wildcard.
Match before lstat() to avoid accessing the worktree for entries that
cannot be shown. Treat this as a prefilter: do not update ps_matched,
and retain the match in show_ce() so --error-unmatch is satisfied only
by entries that the selected modes actually show.
Prefilter only a single pathspec item, bounding the added work for each
index entry. Applying match_pathspec() to multiple arguments can cost
more than the lstat() calls it avoids. In a synthetic repository with
10,000 clean files, passing every path to ls-files --modified increased
runtime from 112.5 ms to 494.1 ms when the prefilter was unconditional.
With $parent and $this exported as paths to binaries built from the
parent and this commit, on a repository with 881,290 index entries:
Junio C Hamano [Fri, 12 Jun 2026 12:41:40 +0000 (05:41 -0700)]
Merge branch 'master' of https://github.com/j6t/git-gui
* 'master' of https://github.com/j6t/git-gui:
git-gui: silence install recipes under "make -s"
git-gui: add gui and pick as explicit subcommands
git-gui: check browser/blame arguments carefully
git-gui: allow specifying path '.' to the browser
git-gui: try harder to find worktree from gitdir
git-gui: simplify [is_bare] to report if a worktree is known
git-gui: use git rev-parse for worktree discovery
git-gui: use rev-parse exclusively to find a repository
git-gui: use --absolute-git-dir
git-gui: do not change global vars in choose_repository::pick
git-gui: guard set/unset of GIT_DIR and GIT_WORK_TREE
git-gui: remove unnecessary 'cd $_gitworktree' from do_gitk
git-gui: use HEAD as current branch when detached
Johannes Sixt [Fri, 12 Jun 2026 09:05:28 +0000 (11:05 +0200)]
Merge branch 'ml/repo-discovery'
* ml/repo-discovery:
git-gui: add gui and pick as explicit subcommands
git-gui: check browser/blame arguments carefully
git-gui: allow specifying path '.' to the browser
git-gui: try harder to find worktree from gitdir
git-gui: simplify [is_bare] to report if a worktree is known
git-gui: use git rev-parse for worktree discovery
git-gui: use rev-parse exclusively to find a repository
git-gui: use --absolute-git-dir
git-gui: do not change global vars in choose_repository::pick
git-gui: guard set/unset of GIT_DIR and GIT_WORK_TREE
git-gui: remove unnecessary 'cd $_gitworktree' from do_gitk
git-gui: use HEAD as current branch when detached
Paired octothorpes are used in AsciiDoc to mark highlighted text,
<mark> being the equivalent HTML tag. To use the symbol as a literal
character, it can be escaped with backticks.
Do so in git-config.adoc.
While at it, tweak the text slightly to make it scan better.
Signed-off-by: Tuomas Ahola <taahol@utu.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Tuomas Ahola [Thu, 11 Jun 2026 16:19:44 +0000 (19:19 +0300)]
doc: config: terminate runaway lists
There are many places in git-config(1) where paragraphs that should
logically come after a list are instead appended to the last item of
the list. This is a well-documented quirk of AsciiDoc, and can be
mitigated by enclosing the list in an open block:
--
* first item
* last item
--
+
New paragraph after the list.
Fix the issue accordingly.
Signed-off-by: Tuomas Ahola <taahol@utu.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano [Wed, 10 Jun 2026 21:39:08 +0000 (14:39 -0700)]
t1400: have fifo test clean after itself
One test in this script creates a pair of FIFOs, "in" and "out",
that are named so generically that later tests may be tempted to use
them. By the time those later tests run a command with its output
redirected to the file (e.g., "git foobar >out"), however, nobody is
reading from the lingering FIFO, and the test gets blocked forever.
Junio C Hamano [Thu, 11 Jun 2026 11:31:19 +0000 (04:31 -0700)]
Merge branch 'hn/macos-linker-warning'
A linker warning on macOS when building with Xcode 16.3 or newer has
been avoided by passing -fno-common to the compiler when a
sufficiently new linker is detected.
* hn/macos-linker-warning:
config.mak.uname: avoid macOS linker warning on Xcode 16.3+
In t3070-wildmatch, "via ls-files" test variants with patterns
containing backslash escapes are now skipped on Windows, avoiding 36
test failures caused by pathspec separator conversion.
* kk/wildmatch-windows-ls-files-prereq:
t3070: skip ls-files tests with backslash patterns on Windows
Junio C Hamano [Thu, 11 Jun 2026 11:31:18 +0000 (04:31 -0700)]
Merge branch 'lp/http-fetch-pack-index-leak-fix'
A memory leak in `fetch_and_setup_pack_index()` when verification of
the downloaded pack index fails has been plugged. Also an obsolete
`unlink()` call on parse failure has been cleaned up.
* lp/http-fetch-pack-index-leak-fix:
http: fix memory leak in fetch_and_setup_pack_index()
http: cleanup function fetch_and_setup_pack_index()
Junio C Hamano [Thu, 11 Jun 2026 11:31:18 +0000 (04:31 -0700)]
Merge branch 'ps/odb-source-loose'
The loose object source has been refactored into a proper `struct
odb_source`.
* ps/odb-source-loose:
odb/source-loose: drop pointer to the "files" source
odb/source-loose: stub out remaining callbacks
odb/source-loose: wire up `write_object_stream()` callback
object-file: refactor writing objects to use loose source
odb/source-loose: wire up `write_object()` callback
loose: refactor object map to operate on `struct odb_source_loose`
odb/source-loose: wire up `freshen_object()` callback
odb/source-loose: drop `odb_source_loose_has_object()`
odb/source-loose: wire up `count_objects()` callback
odb/source-loose: wire up `find_abbrev_len()` callback
odb/source-loose: wire up `for_each_object()` callback
odb/source-loose: wire up `read_object_stream()` callback
odb/source-loose: wire up `read_object_info()` callback
odb/source-loose: wire up `close()` callback
odb/source-loose: wire up `reprepare()` callback
odb/source-loose: start converting to a proper `struct odb_source`
odb/source-loose: store pointer to "files" instead of generic source
odb/source-loose: move loose source into "odb/" subsystem
Junio C Hamano [Thu, 11 Jun 2026 11:31:17 +0000 (04:31 -0700)]
Merge branch 'mm/line-log-cleanup'
The `git log -L` implementation has been refactored to use the
standard diff output pipeline, enabling pickaxe and diff-filter to
work as expected. Additionally, metadata-only diff formats like
--raw and --name-only are now supported with -L.
* mm/line-log-cleanup:
line-log: allow non-patch diff formats with -L
line-log: integrate -L output with the standard log-tree pipeline
revision: move -L setup before output_format-to-diff derivation
Tamir Duberstein [Wed, 10 Jun 2026 18:50:01 +0000 (11:50 -0700)]
describe: limit default ref iteration to tags
Without --all, git describe ignores refs outside refs/tags/. Commit 8a5a1884e9 (Avoid accessing non-tag refs in git-describe unless --all is
requested, 2008-02-24) moved this check ahead of object lookup. That
avoided loading objects for irrelevant refs, but the backend still has
to yield every ref before get_name() can reject it.
Pass refs/tags/ to the iterator so the backend can avoid visiting those
refs in the first place.
The new perf test creates 10,000 unrelated packed refs. It measures:
git describe --exact-match HEAD
The runtime drops from 0.03(0.01+0.01) to 0.02(0.00+0.00). In a
repository with 120,532 refs but only 330 tags, the same command went
from 171.7 ms to 9.9 ms.
Signed-off-by: Tamir Duberstein <tamird@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jayesh Daga [Tue, 31 Mar 2026 15:34:26 +0000 (15:34 +0000)]
unpack-trees: use repository from index instead of global
unpack_trees() currently initializes its repository from the
global 'the_repository', even though a repository instance is
already available via the source index.
Use 'o->src_index->repo' instead of the global variable,
reducing reliance on global repository state.
This is a step towards eliminating global repository usage in
unpack_trees().
Suggested-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Jayesh Daga <jayeshdaga99@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pushkar Singh [Tue, 9 Jun 2026 13:47:42 +0000 (13:47 +0000)]
transport-helper: fix TSAN race in transfer_debug()
Currently, transfer_debug() lazily initializes a static variable based
on GIT_TRANSLOOP_DEBUG. Since the function may be called from multiple
worker threads, this initialization is racy and is therefore suppressed
in .tsan-suppressions.
Initialize the variable in bidirectional_transfer_loop() before any
worker threads or processes are created. This patch removes the race and
allows dropping the corresponding TSAN suppression.
Signed-off-by: Pushkar Singh <pushkarkumarsingh1970@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano [Tue, 9 Jun 2026 01:04:51 +0000 (10:04 +0900)]
Merge branch 'ib/doc-push-default-simple'
The documentation for `push.default = simple` has been clarified to
better explain its behavior, making it clear that it pushes the
current branch to a same-named branch on the remote, and detailing
the upstream requirements for centralized workflows.
Junio C Hamano [Tue, 9 Jun 2026 01:04:50 +0000 (10:04 +0900)]
Merge branch 'ua/push-remote-group'
"git push" learned to take a "remote group" name to push to, which
causes pushes to multiple places, just like "git fetch" would do.
* ua/push-remote-group:
push: support pushing to a remote group
remote: move remote group resolution to remote.c
remote: fix sign-compare warnings in push_cas_option
Junio C Hamano [Tue, 9 Jun 2026 01:04:49 +0000 (10:04 +0900)]
Merge branch 'th/promisor-quiet-per-repo'
The "promisor.quiet" configuration variable was not used from
relevant submodules when commands like "grep --recurse-submodules"
triggered a lazy fetch, which has been corrected.
* th/promisor-quiet-per-repo:
promisor-remote: fix promisor.quiet to use the correct repository
Junio C Hamano [Tue, 9 Jun 2026 01:04:49 +0000 (10:04 +0900)]
Merge branch 'tb/bitmap-build-performance'
Reachability bitmap generation has been significantly optimized. By
reordering tree traversal, caching object positions, and refining how
pseudo-merge bitmaps are constructed, the performance of "git repack
--write-midx-bitmaps" is improved, especially for large repositories
and when using pseudo-merges.
* tb/bitmap-build-performance:
pack-bitmap: build pseudo-merge bitmaps after regular bitmaps
pack-bitmap: remember pseudo-merge parents
pack-bitmap: sort bitmaps before XORing
pack-bitmap: cache object positions during fill
pack-bitmap: consolidate `find_object_pos()` success path
pack-bitmap: reuse stored selected bitmaps
pack-bitmap: check subtree bits before recursing
pack-bitmap: pass object position to `fill_bitmap_tree()`
Andrew Kreimer [Sun, 31 May 2026 18:43:58 +0000 (21:43 +0300)]
doc: fix typos via codespell
There are some typos in the documentation, comments, etc.
Fix them via codespell, and then adjust the "dump" files
used by the subversion tests to match the updated contents.
Signed-off-by: Andrew Kreimer <algonell@gmail.com>
[dscho noticed and fixed the problems in svn test] Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
[jc did final assembling of the three patches] Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano [Sun, 7 Jun 2026 14:58:25 +0000 (23:58 +0900)]
Merge branch 'ja/doc-synopsis-style-again'
A batch of documentation pages has been updated to use the modern
synopsis style.
* ja/doc-synopsis-style-again:
doc: convert git-imap-send synopsis and options to new style
doc: convert git-apply synopsis and options to new style
doc: convert git-am synopsis and options to new style
doc: convert git-grep synopsis and options to new style
doc: git bisect: clarify the usage of the synopsis vs actual command
doc: convert git-bisect to synopsis style
Junio C Hamano [Sun, 7 Jun 2026 14:58:25 +0000 (23:58 +0900)]
Merge branch 'kk/commit-reach-optim'
The check for non-stale commits in the priority queue used by
`paint_down_to_common` and `ahead_behind` has been optimized by
replacing an O(N) scan with an O(1) counter, yielding performance
improvements in repositories with wide histories.
* kk/commit-reach-optim:
commit-reach: replace queue_has_nonstale() scan with O(1) tracking
commit-reach: deduplicate queue entries in paint_down_to_common
object.h: fix stale entries in object flag allocation table
Junio C Hamano [Sun, 7 Jun 2026 14:58:24 +0000 (23:58 +0900)]
Merge branch 'ds/restore-sparse-index'
'git restore --staged' has been optimized to avoid unnecessarily expanding
the sparse index when operating on paths within the sparse checkout
definition, by handling sparse directory entries at the tree level.
* ds/restore-sparse-index:
restore: avoid sparse index expansion
t1092: test 'git restore' with sparse index
Junio C Hamano [Sun, 7 Jun 2026 14:58:24 +0000 (23:58 +0900)]
Merge branch 'ar/receive-pack-worktree-env'
The GIT_WORK_TREE variable prepared to invoke the push-to-checkout
hook was leaking into the environment even when there was no hook
used and broke the default push-to-deploy (i.e., let "git checkout"
update the working tree only when the working tree is clean).
* ar/receive-pack-worktree-env:
receive-pack: fix updateInstead with core.worktree
Harald Nordgren [Thu, 4 Jun 2026 06:48:50 +0000 (06:48 +0000)]
git-gui: silence install recipes under "make -s"
Several install and uninstall recipes embed "echo" calls that fire as
part of the recipe itself, so the install banners (DEST, INSTALL,
LINK, REMOVE) were visible whenever the variables expand non-empty.
Guard the whole "ifndef V" block on "-s" so the loud variants are
selected only when "-s" is absent and V=1 is unset. The existing
"-s" check also had its findstring arguments in the wrong order
(needle "-s" never fit in haystack "s"), so swap them while moving
the check to wrap the block.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Previously, we did not install any handler for Ctrl+C, but now we really
want to because the MSYS2 runtime learned the trick to call the
ConsoleCtrlHandler when Ctrl+C was pressed.
With this, hitting Ctrl+C while `git log` is running will only terminate
the Git process, but not the pager. This finally matches the behavior on
Linux and on macOS.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
The TerminateProcess() function does not actually leave the child
processes any chance to perform any cleanup operations. This is bad
insofar as Git itself expects its signal handlers to run.
A symptom is e.g. a left-behind .lock file that would not be left behind
if the same operation was run, say, on Linux.
To remedy this situation, we use an obscure trick: we inject a thread
into the process that needs to be killed and to let that thread run the
ExitProcess() function with the desired exit status. Thanks J Wyman for
describing this trick.
The advantage is that the ExitProcess() function lets the atexit
handlers run. While this is still different from what Git expects (i.e.
running a signal handler), in practice Git sets up signal handlers and
atexit handlers that call the same code to clean up after itself.
In case that the gentle method to terminate the process failed, we still
fall back to calling TerminateProcess(), but in that case we now also
make sure that processes spawned by the spawned process are terminated;
TerminateProcess() does not give the spawned process a chance to do so
itself.
Please note that this change only affects how Git for Windows tries to
terminate processes spawned by Git's own executables. Third-party
software that *calls* Git and wants to terminate it *still* need to make
sure to imitate this gentle method, otherwise this patch will not have
any effect.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
setup: construct object database in `apply_repository_format()`
With the preceding changes we now always construct the repository's
object database before applying the repository format. Remove this
duplication by constructing it in `apply_repository_format()` instead.
Note that we create the object database _after_ having set up the
repository's hash algorithm, but _before_ setting the compat hash
algorithm. This is intentional:
- Constructing the object database may require knowledge of its
intended object format.
- Setting up the compatibility hash requires the object database to be
initialized already, because we immediately read the loose object
map.
The first point is sensible, the second maybe a little less so. Ideally,
it should be the responsibility of the object database itself to
initialize any data structures required for the compatibility hash. But
this would require further changes, so this is kept as-is for now.
Further note that this requires us to move handling of the environment
variables GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES into
the repository format, as well. This allows the caller more flexibility
around whether or not those environment variables are being honored, as
we want to respect them in "setup.c", but not in "repository.c".
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>