Commit Graph

24947 Commits

Author SHA1 Message Date
Johannes Schindelin
a0bab4bad1 Merge branch 'dscho-avoid-d-f-conflict-in-vs-master'
Merge this early to resolve merge conflicts early.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2026-06-29 19:06:17 +02:00
Johannes Schindelin
ad1a5846db mingw: allow git.exe to be used instead of the "Git wrapper"
Git for Windows wants to add `git.exe` to the users' `PATH`, without
cluttering the latter with unnecessary executables such as `wish.exe`.
To that end, it invented the concept of its "Git wrapper", i.e. a tiny
executable located in `C:\Program Files\Git\cmd\git.exe` (originally a
CMD script) whose sole purpose is to set up a couple of environment
variables and then spawn the _actual_ `git.exe` (which nowadays lives in
`C:\Program Files\Git\mingw64\bin\git.exe` for 64-bit, and the obvious
equivalent for 32-bit installations).

Currently, the following environment variables are set unless already
initialized:

- `MSYSTEM`, to make sure that the MSYS2 Bash and the MSYS2 Perl
  interpreter behave as expected, and

- `PLINK_PROTOCOL`, to force PuTTY's `plink.exe` to use the SSH
  protocol instead of Telnet,

- `PATH`, to make sure that the `bin` folder in the user's home
  directory, as well as the `/mingw64/bin` and the `/usr/bin`
  directories are included. The trick here is that the `/mingw64/bin/`
  and `/usr/bin/` directories are relative to the top-level installation
  directory of Git for Windows (which the included Bash interprets as
  `/`, i.e. as the MSYS pseudo root directory).

Using the absence of `MSYSTEM` as a tell-tale, we can detect in
`git.exe` whether these environment variables have been initialized
properly. Therefore we can call `C:\Program Files\Git\mingw64\bin\git`
in-place after this change, without having to call Git through the Git
wrapper.

Obviously, above-mentioned directories must be _prepended_ to the `PATH`
variable, otherwise we risk picking up executables from unrelated Git
installations. We do that by constructing the new `PATH` value from
scratch, appending `$HOME/bin` (if `HOME` is set), then the MSYS2 system
directories, and then appending the original `PATH`.

Side note: this modification of the `PATH` variable is independent of
the modification necessary to reach the executables and scripts in
`/mingw64/libexec/git-core/`, i.e. the `GIT_EXEC_PATH`. That
modification is still performed by Git, elsewhere, long after making the
changes described above.

While we _still_ cannot simply hard-link `mingw64\bin\git.exe` to `cmd`
(because the former depends on a couple of `.dll` files that are only in
`mingw64\bin`, i.e. calling `...\cmd\git.exe` would fail to load due to
missing dependencies), at least we can now avoid that extra process of
running the Git wrapper (which then has to wait for the spawned
`git.exe` to finish) by calling `...\mingw64\bin\git.exe` directly, via
its absolute path.

Testing this is in Git's test suite tricky: we set up a "new" MSYS
pseudo-root and copy the `git.exe` file into the appropriate location,
then verify that `MSYSTEM` is set properly, and also that the `PATH` is
modified so that scripts can be found in `$HOME/bin`, `/mingw64/bin/`
and `/usr/bin/`.

This addresses https://github.com/git-for-windows/git/issues/2283

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2026-06-29 19:06:16 +02:00
Johannes Schindelin
0350f6c4f8 t5505/t5516: fix white-space around redirectors
The convention in Git project's shell scripts is to have white-space
_before_, but not _after_ the `>` (or `<`).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2026-06-29 19:06:12 +02:00
Johannes Schindelin
40b9c78d20 t5505/t5516: allow running without .git/branches/ in the templates
When we commit the template directory as part of `make vcxproj`, the
`branches/` directory is not actually commited, as it is empty.

Two tests were not prepared for that situation.

This developer tried to get rid of the support for `.git/branches/` a
long time ago, but that effort did not bear fruit, so the best we can do
is work around in these here tests.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2026-06-29 19:06:12 +02:00
Junio C Hamano
7fb089f411 Merge branch 'jk/t5551-expensive-test-timeouts-fix'
The Apache timeout in HTTP tests has been increased to prevent test
failures on heavily loaded CI runners. The tests creating an
enormous number of refs have been isolated to their own repositories
to avoid slowing down subsequent tests.

* jk/t5551-expensive-test-timeouts-fix:
  t5551: put many-tags case into its own repo
  t/lib-httpd: bump apache timeout
2026-06-29 07:57:17 -07:00
Jeff King
f6ef747a7c t5551: put many-tags case into its own repo
Most of the t5551 http fetch tests use a handful of refs. But there are
a few test cases which check our handling of large numbers of refs.
These tests use the same server-side repo, so all subsequent tests end
up having to consider those extra refs, too.

The result is that the test script is a bit slower than it needs to be.
In a normal run, moving the "2,000 tags" test into its own repo drops my
runtime for the whole script from ~2.7s to ~1.9s.

This is a modest gain, but when we add the "--long" flag it gets much
bigger. There we trigger a test (marked with EXPENSIVE) that adds
100,000 tags, and the script runtime jumps to ~95s. But if we use the
same "many tags" repo for that, our runtime drops to just ~37s.

This is a pretty easy win to drop the cost of the script. It may even be
a larger gain on a heavily loaded system, since one of the main costs
here is unpacked refs, which are heavy on system time and I/O costs.

It's possible we are reducing test coverage, since all of those other
tests were inadvertently using large ref advertisements (and thus could
have uncovered some unexpected interaction). But that seems somewhat
unlikely; the tests targeted at the large number of refs are doing
roughly similar things to the other tests.

Note that the real performance culprit is the 100k-tag --long test, not
the 2k-tag one. So we could just let the 100k one use its own repo, and
keep the 2k tags in the main repo. But since these two tests are
somewhat interlinked, it's easier to just move them both (and it does
provide a small gain even for the 2000-tag test). I also notice that the
2000-tag test is gated on the CMDLINE_LIMIT prereq, and without that the
later EXPENSIVE test will fail (since we won't have a too-many-refs
clone). Nobody seems to have noticed or complained after many years, and
I left it alone for this patch.

Signed-off-by: Jeff King <peff@peff.net>
[jc: made the new "many-tags.git" bare to match the original "repo.git"]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-29 07:54:42 -07:00
Jeff King
dc51aedd53 t/lib-httpd: bump apache timeout
Since enabling more tests with 7a094d68a2 (ci: run expensive tests on
push builds to integration branches, 2026-05-08), we sometimes see test
failures or timeouts in GitHub CI. The culprit seems to be the "enormous
ref negotiation" test in t5551, which creates ~100k tag refs in our http
server-side repo.

Iterating through the loose refs of this repo to generate a ref
advertisement can take a long time, especially on a platform with slow
I/O. On my otherwise unloaded local machine, a cold cache ref
advertisement takes ~10s. On a busy CI machine running tests in
parallel, it can presumably top 60s, which runs afoul of Apache's
default CGI timeout.

The result in t5551 is a test failure, where Apache simply hangs up the
connection and the client reports an error. But worse, t5559 runs the
same test with HTTP/2, and a bug in Apache causes the connection to hang
indefinitely! We eventually see this as a CI timeout after 6 hours.

Let's bump Apache's timeout to something much larger: 600 seconds. This
doesn't eliminate the possibility of a timeout, but it makes it much
less likely. It should eliminate both the test failures and the CI
timeouts in practice, and it protects us from running into similar
problems with other tests in the future.

There are two counter-arguments to consider.

One, could/should we just make the test faster? Probably yes. The
biggest mistake here is having such an absurd number of unpacked refs on
a system which is bottle-necked on I/O. But I think it's worth bumping
the timeout so that we can fix this (and possibly other) correctness
issues, and then consider performance separately (which we'll do in
subsequent patches).

And two, is this just papering over a problem that users might see in
the real world? We could teach Git to handle this case more gracefully
with optimizations or keep-alives. But I think it's really an artificial
situation. You need a combination of this silly number of loose refs,
plus a very heavily loaded system. If you were trying to run a real
server and it took more than 60s to generate the ref advertisement, I
don't think the timeout is your biggest problem. Your crappy service is,
and you should adjust your resources to match your load. I.e., it is
probably reasonable for Git to assume that advertisements happen
fast-ish and don't need protocol-level keepalives.

Though the patch here is small, tons of work went into analyzing the
problem. Many thanks to the contributors credited below.

Helped-by: Michael Montalbo <mmontalbo@gmail.com>
Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-28 08:32:36 -07:00
Junio C Hamano
6c3d7b7355 Merge branch 'ps/t4216-tap-fix'
TAP output breakage fix.

* ps/t4216-tap-fix:
  t4216: fix no-op test that breaks TAP output
2026-06-25 19:49:01 -07:00
Patrick Steinhardt
f0411a4c71 t4216: fix no-op test that breaks TAP output
In t4216 we have have a prerequisite that is active in case the system's
`char` type is signed by default. This prerequisite isn't really used by
anything though: while it is used to guard one of our tests, that
specific test is essentially a no-op. So all this infrastructure does is
to provide some debugging hint to a reader that pays a lot of attention.

Besides that, the way we set up the prerequisite also results in broken
TAP output on systems where `char` is unsigned by default: we use
`test_cmp()` to diff two files outside of of any test body, and if the
files differ we enable the prerequisite. If so, the call to `test_cmp()`
would also print output, and that output is of course not valid TAP
output.

That wasn't a problem before 389c83025d (t: let prove fail when parsing
invalid TAP output, 2026-06-04), because our TAP parser was configured
to be lenient. But starting with that commit, t4216 is now failing on
systems with unsigned chars.

Drop the whole infrastructure. The prerequisite is not used anywhere
else, and the only location where it's used doesn't really provide much
value.

Reported-by: Todd Zullinger <tmz@pobox.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Tested-by: Todd Zullinger <tmz@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-25 13:17:40 -07:00
Junio C Hamano
02bb39c5cb Merge branch 'js/objects-larger-than-4gb-on-windows-more'
* 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
2026-06-21 16:41:38 -07:00
Junio C Hamano
8632b5c49d 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
2026-06-17 11:10:12 -07:00
Junio C Hamano
621962aa7a 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
2026-06-17 11:10:12 -07:00
Junio C Hamano
49cb068fb2 Merge branch 'jc/t1400-fifo-cleanup'
Test cleanup.

* jc/t1400-fifo-cleanup:
  t1400: have fifo test clean after itself
2026-06-17 11:10:11 -07:00
Junio C Hamano
b4970f8448 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
2026-06-17 11:10:11 -07:00
Junio C Hamano
4c2c7677e4 Merge branch 'ta/typofixes'
Typofixes

* ta/typofixes:
  docs: fix typos
2026-06-16 09:01:03 -07:00
Junio C Hamano
5105e38948 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
2026-06-16 09:01:03 -07:00
Junio C Hamano
5255d04a9c Merge branch 'wy/docs-typofixes'
Various typos, grammatical errors, and duplicated words in both
documentation and code comments have been corrected.

* wy/docs-typofixes:
  docs: fix typos and grammar
2026-06-16 09:01:03 -07:00
Junio C Hamano
e02da45693 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
2026-06-16 09:01:02 -07:00
Junio C Hamano
7afc0f184b 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
2026-06-16 09:01:02 -07:00
Junio C Hamano
c534ec3a5d 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.

* mf/revision-max-count-oldest:
  bash-completions: add --max-count-oldest
  revision.c: implement --max-count-oldest
2026-06-16 09:01:02 -07:00
Johannes Schindelin
c6a4629e32 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>
2026-06-15 07:45:41 -07:00
Johannes Schindelin
33afe87338 patch-delta: use size_t for sizes
`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>
2026-06-15 07:45:40 -07:00
Junio C Hamano
ff1784217f Merge branch 'ak/typofixes'
Typofixes.

* ak/typofixes:
  doc: fix typos via codespell
2026-06-15 07:42:00 -07:00
Junio C Hamano
4d1d7b933e 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
2026-06-15 07:42:00 -07:00
Junio C Hamano
cfe6682042 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
2026-06-15 07:41:59 -07:00
Junio C Hamano
8b0f02bbbb 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
2026-06-15 07:41:59 -07:00
Elijah Newren
fbcc5408fc 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 80c928d947 (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 368d19b0b7 (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>
2026-06-14 08:24:08 -07:00
Tamir Duberstein
3f5203eeb4 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:

    hyperfine --warmup 0 --runs 3 \
        --command-name parent \
        '$parent -c core.fsmonitor=false ls-files --deleted -- README.md >/dev/null' \
        --command-name this-commit \
        '$this -c core.fsmonitor=false ls-files --deleted -- README.md >/dev/null'

reported means of 65.790 seconds for the parent and 4.987 seconds for
this commit.

Link: https://lore.kernel.org/r/xmqqfr2tnfk0.fsf@gitster.g
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-12 12:47:21 -07:00
Junio C Hamano
e8f12e0e95 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.

Clean them up when the test finishes.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-11 05:34:40 -07:00
Junio C Hamano
15acf6d533 Merge branch 'kk/wildmatch-windows-ls-files-prereq'
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
2026-06-11 04:31:19 -07:00
Junio C Hamano
53ff393204 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
2026-06-11 04:31:17 -07:00
Tamir Duberstein
55088ac8a4 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>
2026-06-10 12:38:49 -07:00
Junio C Hamano
2c677d20b6 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
2026-06-09 10:04:50 +09:00
Junio C Hamano
fca09c8fc2 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
2026-06-09 10:04:50 +09:00
Andrew Kreimer
014c454799 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>
2026-06-08 00:21:35 +09:00
Junio C Hamano
de5383c2ce Merge branch 'aj/stash-patch-optimize-temporary-index'
"git stash -p" has been optimized by reusing cached index
entries in its temporary index, avoiding unnecessary lstat()
calls on unchanged files.

* aj/stash-patch-optimize-temporary-index:
  stash: reuse cached index entries in --patch temporary index
2026-06-07 23:58:25 +09:00
Junio C Hamano
7450009e6f 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
2026-06-07 23:58:24 +09:00
Junio C Hamano
17204228cf 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
2026-06-07 23:58:24 +09:00
Tuomas Ahola
e6145d1241 docs: fix typos
Fix some typos and grammar errors in comments and documentation files.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 22:27:24 +09:00
Patrick Steinhardt
027e3b3d38 t0001: plug test gaps for git-init(1) with GIT_OBJECT_DIRECTORY
In subsequent commits we'll rework how we set up the repository. This is
a somewhat intricate and thus fragile sequence; there's many things that
can go subtly wrong, and there are lots of interesting interactions that
one can discover.

One such discovered edge case was the interaction between git-init(1)
and the "GIT_OBJECT_DIRECTORY" environment variable. When set, the
behaviour is that the object directory should be created at the path
that the variable points to. This behaviour is documented as such in
its man page:

  If the object storage directory is specified via the
  GIT_OBJECT_DIRECTORY environment variable then the sha1 directories
  are created underneath; otherwise, the default $GIT_DIR/objects
  directory is used.

Curiously enough though we don't seem to have any tests that exercise
this directly, and thus a subsequent commit inadvertently would have
broken this expectation.

Plug this test gap.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:38 +09:00
Patrick Steinhardt
389c83025d t: let prove fail when parsing invalid TAP output
To make the result of our tests accessible we use the TAP protocol. This
protocol is parsed by either prove or by Meson. Unfortunately, these two
tools differ when it comes to their strictness when parsing the
protocol:

  - Prove by default happily accepts lines not specified by the
    protocol.

  - Meson will also accept such lines, but prints a big and ugly warning
    message.

We have fixed our test suite in the past to not print invalid TAP lines
anymore via b1dc2e796e (Merge branch 'ps/meson-tap-parse', 2025-06-17).
But as none of our tools perform a strict check it's still possible for
broken tests to sneak back in, like for example in 362f69547f (Merge
branch 'ps/t1006-tap-fix', 2025-07-16). This doesn't hurt at all when
using prove, but it's quite annoying when using Meson due to the
generated warnings.

Unfortunately, there doesn't seem to be a portable way to make all tools
complain about violations of the TAP format. The TAP 14 specification
has added pragmas to the protocol that would allow us to say `pragma
+strict`, and the effect of that would be to treat invalid TAP lines as
a test failure. But the release of TAP 14 is still rather recent, and
Test-Harness for example only gained support for it in version 3.48,
which was released in 2023.

In fact though, this pragma was already introduced as an inofficial
extension of the TAP protocol with Test-Harness 3.10, released in 2008.
So while not all tools understand the pragma, at least prove does for a
long time.

Unconditionally enable the pragma when using prove so that we'll detect
tests that emit broken TAP output right away. This would have detected
the issues fixed in preceding commits:

    $ prove t7527-builtin-fsmonitor.sh
    t7527-builtin-fsmonitor.sh .. All 69 subtests passed
            (less 6 skipped subtests: 63 okay)

    Test Summary Report
    -------------------
    t7527-builtin-fsmonitor.sh (Wstat: 0 Tests: 69 Failed: 0)
      Parse errors: Unknown TAP token: "Initialized empty Git repository in /tmp/git/test_fsmonitor_smoke/.git/"

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt
c2d2d173ae t/lib-git-p4: silence output when killing p4d and its watchdog
When stopping the p4d watchdog process via "kill -9", the shell may
print a job-control notification like:

  ./test-lib.sh: line 1269: 57960 Killed: 9               while true; do
      if test $nr_tries_left -eq 0; then
          kill -9 $p4d_pid; exit 1;
      fi; sleep 1; nr_tries_left=$(($nr_tries_left - 1));
  done 2> /dev/null 4>&2  (wd: ~)

This message is printed asynchronously by the shell when it reaps the
process. While harmless right now, this will cause breakage once we
enable strict parsing of the TAP protocol in a subsequent commit.

Fix this by using `wait` so that we can synchronously reap the watchdog
process and swallow the diagnostic.

While at it, deduplicate the logic we have in `stop_p4d_and_watchdog ()`
and `stop_and_cleanup_p4d ()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt
d11968661e t/test-lib: silence EBUSY errors on Windows during test cleanup
When tests have finished we clean up the trash directory via `rm -rf`.
On Windows this can fail with EBUSY in cases where a process still holds
some of the files open, for example when we have spawned a daemonized
process that wasn't properly terminated. We thus retry several times,
but every failure will result in error messages being printed, and that
in turn breaks the TAP output format.

One such case where this is causing issues is in t921x, which contains
tests related to Scalar. Some tests spawn the fsmonitor daemon, and we
never properly terminate it.

The obvious fix would be to ensure that we never leak any processes, but
that gets ugly fast. Instead, let's work around the issue by silencing
error messages printed by the `rm -rf` calls. We already know to print
an error when the retry loop fails, so we don't loose much.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt
b1688db759 t7810: turn MB_REGEX check into a lazy prereq
In t7810 we verify whether the system has proper multibyte locale
support by executing `test-tool regex` with a unicode character. When
this check fails though we'll output an error that breaks the TAP
format.

Fix this issue by turning the logic into a lazy prerequisite.

Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt
bf3ed750cb t7527: fix broken TAP output
Before running the tests in t7527 we first verify whether the fsmonitor
even works, which seems to depend on the actual filesystem that is in
use. The verification executes outside of any prerequisite or test body,
so its stdout/stderr is not being redirected.

The consequence of this is that any command that prints to stdout/stderr
may break the TAP specification by printing invalid lines. And in fact
we already do that, as git-init(1) prints the path to the created Git
repository by default.

Fix this issue by moving the logic into a lazy prerequisite.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Harald Nordgren
03c29e2e98 config: improve diagnostic for "set" with missing value
"git config set pull.rebase=false" currently fails with "wrong
number of arguments", and the implicit form "git config
pull.rebase=false" fails with "invalid key". Neither points at
the real problem: the value is missing.

Report that directly, and when the argument has the shape
"<valid-key>=<value>", also suggest the split form:

    $ git config set pull.rebase=false
    error: missing value to set to the variable 'pull.rebase=false'
    hint: did you mean "git config set pull.rebase false"?

When the prefix before "=" is not a valid key, drop the hint:

    $ git config set foo=bar
    error: missing value to set to a variable with an invalid name 'foo=bar'

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:39:54 +09:00
Mirko Faina
bb4ce23284 revision.c: implement --max-count-oldest
"--max-count" is a commit limiting option and sets a maximum amount
of commits to be shown. If a user wants to see only the first N
commits of the history (the oldest commits) they'd have to do
something like

    git log $(git rev-list HEAD | tail -n N | head -n 1)

This is not very user-friendly.

Teach get_revision() the --max-count-oldest option.

Signed-off-by: Mirko Faina <mroik@delayed.space>
[jc: fixed up t4202 <xmqq7boy4o05.fsf@gitster.g>]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:37:52 +09:00
Luna Schwalbe
4018dc29ee doc: document and test @ prefix for raw timestamps
The Git internal date format `<unix-timestamp> <time-zone-offset>`
fails to parse when the timestamp is less than 100,000,000 (fewer than
9 digits). This happens to avoid potential ambiguity with other date
formats such as `YYYYMMDD`, especially when used with approxidate.

To force the parser to interpret the value as a raw timestamp, it must
be prefixed with `@` (e.g., `@0 +0000`). This behavior was introduced
in 2c733fb24c (parse_date(): '@' prefix
forces git-timestamp, 2012-02-02) but was never documented.

Document the `@` prefix in `Documentation/date-formats.adoc` to make
this behavior explicit. Also add test cases to `t/t0006-date.sh` to
verify and demonstrate the difference between prefixed and unprefixed
small timestamps (e.g., `@2000` vs `2000`).

Signed-off-by: Luna Schwalbe <dev@luna.gl>
Co-authored-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-02 18:13:12 +09:00
Junio C Hamano
ffaa2eddd0 Merge branch 'ds/path-walk-filters'
The "git pack-objects --path-walk" traversal has been integrated
with several object filters, including blobless and sparse filters.

* ds/path-walk-filters:
  path-walk: support `combine` filter
  path-walk: support `object:type` filter
  path-walk: support `tree:0` filter
  t6601: tag otherwise-unreachable trees
  pack-objects: support sparse:oid filter with path-walk
  path-walk: add pl_sparse_trees to control tree pruning
  path-walk: support blob size limit filter
  backfill: die on incompatible filter options
  path-walk: support blobless filter
  path-walk: always emit directly-requested objects
  t/perf: add pack-objects filter and path-walk benchmark
  pack-objects: pass --objects with --path-walk
  t5620: make test work with path-walk var
2026-06-02 16:15:29 +09:00
Junio C Hamano
15dc60dcd1 Merge branch 'ta/approxidate-noon-fix'
"Friday noon" asked in the morning on Sunday was parsed to be one
day before the specified time, which has been corrected.

* ta/approxidate-noon-fix:
  approxidate: use deferred mday adjustments for "specials"
  approxidate: make "specials" respect fixed day-of-month
  t0006: add support for approxidate test date adjustment
  approxidate: make "today" wrap to midnight
2026-06-02 16:15:29 +09:00