Ensure key CMake option values are part of the CMake output to
facilitate user support when tool updates impact the wider CMake
actions, particularly ongoing 'improvements' in Visual Studio.
These CMake displays perform the same function as the build-options.txt
provided in the main Git for Windows. CMake is already chatty.
The setting of CMAKE_EXPORT_COMPILE_COMMANDS is also reported.
Include the environment's CMAKE_EXPORT_COMPILE_COMMANDS value which
may have been propogated to CMake's internal value.
Testing the CMAKE_EXPORT_COMPILE_COMMANDS processing can be difficult
in the Visual Studio environment, as it may be cached in many places.
The 'environment' may include the OS, the user shell, CMake's
own environment, along with the Visual Studio presets and caches.
See previous commit for arefacts that need removing for a clean test.
Signed-off-by: Philip Oakley <philipoakley@iee.email>
In Git-for-Windows, work on using ARM64 has progressed. The
commit 2d94b77b27 (cmake: allow building for Windows/ARM64, 2020-12-04)
failed to notice that /compat/vcbuild/vcpkg_install.bat will default to
using the "x64-windows" architecture for the vcpkg installation if not set,
but CMake is not told of this default. Commit 635b6d99b3 (vcbuild: install
ARM64 dependencies when building ARM64 binaries, 2020-01-31) later updated
vcpkg_install.bat to accept an arch (%1) parameter, but retained the default.
This default is neccessary for the use case where the project directory is
opened directly in Visual Studio, which will find and build a CMakeLists.txt
file without any parameters, thus expecting use of the default setting.
Also Visual studio will generate internal .sln solution and .vcxproj project
files needed for some extension tools. Inform users of the additional
.sln/.vcxproj generation.
** How to test:
rm -rf '.vs' # remove old visual studio settings
rm -rf 'compat/vcbuild/vcpkg' # remove any vcpkg downloads
rm -rf 'contrib/buildsystems/out' # remove builds & CMake artifacts
with a fresh Visual Studio Community Edition, File>>Open>>(git *folder*)
to load the project (which will take some time!).
check for successful compilation.
The implicit .sln (etc.) are in the hidden .vs directory created by
Visual Studio.
Signed-off-by: Philip Oakley <philipoakley@iee.email>
The CMakeSettings.json file is tool generated. Developers may track it
should they provide additional settings.
Signed-off-by: Philip Oakley <philipoakley@iee.email>
Git's regular Makefile mentions that HOST_CPU should be defined when cross-compiling Git: 37796bca76/Makefile (L438-L439)
This is then used to set the GIT_HOST_CPU variable when compiling Git: 37796bca76/Makefile (L1337-L1341)
Then, when the user runs `git version --build-options`, it returns that value: 37796bca76/help.c (L658)
This commit adds the same functionality to the CMake configuration. Users can now set -DHOST_CPU= to set the target architecture.
Signed-off-by: Dennis Ameling <dennis@dennisameling.com>
Git for Windows' default SSL backend is actually Secure Channel. Let's
not hard-code any backend, just ask for _any_ SSL backend.
This is necessary because we cannot ask for `schannel`, as
https://github.com/microsoft/vcpkg/pull/46459 removed the option to
specify that as a feature.
Signed-off-by: Dennis Ameling <dennis@dennisameling.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
There are no Windows/ARM64 agents in GitHub Actions yet, therefore we
just skip adjusting the `vs-test` job for now.
Signed-off-by: Dennis Ameling <dennis@dennisameling.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
In this context, a "feature" is a dependency combined with its own
dependencies.
Signed-off-by: Ian Bearman <ianb@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The vcpkg downloads may not succeed. Warn careful readers of the time out.
A simple retry will usually resolve the issue.
Signed-off-by: Philip Oakley <philipoakley@iee.email>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The vcpkg_install batch file depends on the availability of a
working Git on the CMD path. This may not be present if the user
has selected the 'bash only' option during Git-for-Windows install.
Detect and tell the user about their lack of a working Git in the CMD
window.
Fixes#2348.
A separate PR https://github.com/git-for-windows/build-extra/pull/258
now highlights the recommended path setting during install.
Signed-off-by: Philip Oakley <philipoakley@iee.email>
The `windows-latest` runner image migration that began on June 8, 2026
and completes on June 15, 2026 switches the default Visual Studio
install from VS 2022 (v17) to VS 2026 (v18), per
https://github.com/actions/runner-images/issues/14017.
CMake 4.x picks up the new generator name "Visual Studio 18 2026"
automatically and, crucially, writes the solution file with the new
`.slnx` (XML) extension rather than `.sln`. See
https://github.com/Kitware/CMake/blob/v4.3.2/Source/cmGlobalVisualStudioGenerator.cxx#L1147-L1159
where `GetSLNFile()` appends an "x" to the filename when the generator
version is `VS18` or newer.
As a result, the `MSBuild` step in the `vs-build` job fails with
MSBUILD : error MSB1009: Project file does not exist.
Switch: git.sln
because the file CMake actually wrote is `git.slnx`. An example of the
failure can be seen at
https://github.com/git-for-windows/git/actions/runs/27264770241/job/80556419519.
Teach the step to prefer `git.slnx` and fall back to `git.sln` so that
it works on both the new image and any runner still on VS 2022 during
the week-long staggered rollout. The conditional is written in
PowerShell rather than bash so the step stays on the default shell:
`microsoft/setup-msbuild@v3` adds `msbuild` to the Windows `PATH` only,
and an MSYS2 bash spawned by the SDK does not pick it up (an earlier
attempt at this fix using `shell: bash` failed with
`msbuild: command not found`, see
https://github.com/git-for-windows/git/actions/runs/27290221733/job/80608493655).
Letting MSBuild itself discover the solution by omitting the project
argument is not an option here either: CMake emits all `*.vcxproj`
files (one per `add_executable`/`add_library`, e.g.
`git-daemon.vcxproj`, `common-main.vcxproj`, `ALL_BUILD.vcxproj`, ...)
into the same build root as the solution file, and MSBuild's
auto-discovery in
`ProcessProjectSwitch()` (`dotnet/msbuild`, `src/MSBuild/XMake.cs`)
rejects that combination as `AmbiguousProjectError` because it only
disambiguates the special case of exactly two projects where one has a
`.proj` extension.
Additionally, drop the `-property:PlatformToolset=v142` argument that
had been carried since 889cacb6 (ci: configure GitHub Actions for
CI/PR, 2020-04-11), when this job was first configured for VS 2019.
The VS 2026 install on `windows-latest` only ships the v144 toolset
along with a v143 compatibility component
(`Microsoft.VisualStudio.Component.VC.14.44.17.14.x86.x64`); v142 is
no longer present, so the explicit pin would now also fail in its own
right. Removing it lets MSBuild use whatever toolset CMake selected
during configuration (v143 on a VS 2022 runner, v144 on a VS 2026 one),
which keeps the configure and build steps consistent with each other
regardless of which image picked up the job.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Assisted-by: Opus 4.7
These fixes have been sent to the Git mailing list but have not been
picked up by the Git project yet.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
In some implementations, `regexec_buf()` assumes that it is fed lines;
Without `REG_NOTEOL` it thinks the end of the buffer is the end of a
line. Which makes sense, but trips up this case because we are not
feeding lines, but rather a whole buffer. So the final newline is not
the start of an empty line, but the true end of the buffer.
This causes an interesting bug:
$ echo content >file.txt
$ git grep --no-index -n '^$' file.txt
file.txt:2:
This bug is fixed by making the end of the buffer consistently the end
of the final line.
The patch was applied from
https://lore.kernel.org/git/20250113062601.GD767856@coredump.intra.peff.net/
Reported-by: Olly Betts <olly@survex.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When a Unix socket is initialized, the current directory's path is
stored so that the cleanup code can `chdir()` back to where it was
before exit.
If the path that needs to be stored exceeds the default size of the
`sun_path` attribute of `struct sockaddr_un` (which is defined as a
108-sized byte array on Linux), a larger buffer needs to be allocated so
that it can hold the path, and it is the responsibility of the
`unix_sockaddr_cleanup()` function to release that allocated memory.
In Git's CI, this stack allocation is not necessary because the code is
checked out to `/home/runner/work/git/git`. Concatenate the path
`t/trash directory.t0301-credential-cache/.cache/git/credential/socket`
and a terminating NUL, and you end up with 96 bytes, 12 shy of the
default `sun_path` size.
However, I use worktrees with slightly longer paths:
`/home/me/projects/git/yes/i/nest/worktrees/to/organize/them/` is more
in line with what I have. When I recently tried to locally reproduce a
failure of the `linux-leaks` CI job, this t0301 test failed (where it
had not failed in CI).
The reason: When `credential-cache` tries to reach its daemon initially
by calling `unix_sockaddr_init()`, it is expected that the daemon cannot
be reached (the idea is to spin up the daemon in that case and try
again). However, when this first call to `unix_sockaddr_init()` fails,
the code returns early from the `unix_stream_connect()` function
_without_ giving the cleanup code a chance to run, skipping the
deallocation of above-mentioned path.
The fix is easy: do not return early but instead go directly to the
cleanup code.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
On Windows, symbolic links come in two flavors: file symlinks and
directory symlinks. Since Git was born on Linux where this distinction
does not exist, Git for Windows has to auto-detect the type by looking
at the target. When the target does not yet exist at symlink creation
time, Git for Windows creates a "phantom" file symlink and later, once
checkout is complete, calls `CreateFileW()` on the target to check
whether it is actually a directory.
If the symlink target is a UNC path (e.g. `\\attacker\share`), this
auto-detection triggers an SMB connection to the remote host. Windows
performs NTLM authentication by default for such connections, which
means a crafted repository can exfiltrate the cloning user's NTLMv2
hash to an attacker-controlled server without any user interaction
beyond `git clone -c core.symlinks=true <url>`.
There are ways to specify UNC paths that start with only a single
backslash (e.g. `\??\UNC\host\share`); All of them do start like
that, though, so let's use that as a tell-tale that we should skip
the auto-detection in `process_phantom_symlink()`. The symlink is
then left as a file symlink (the `mklink` default), and a warning is
emitted suggesting the user set the `symlink` gitattribute to `dir`
if a directory symlink is needed. When the attribute is already set,
auto-detection is never invoked in the first place, so that code path
is unaffected.
This is the same class of vulnerability as CVE-2025-66413
(https://github.com/git-for-windows/git/security/advisories/GHSA-hv9c-4jm9-jh3x)
and follows the same general mitigation pattern that MinTTY adopted for
ANSI escape sequences referencing network share paths
(https://github.com/mintty/mintty/security/advisories/GHSA-jf4m-m6rv-p6c5).
Note that there are legitimate paths starting with a single backslash
that are _not_ network paths: drive-less absolute paths are interpreted
as relative to the current working directory's drive. In practice, these
are highly uncommon (and brittle, just one working directory change
away from breaking). In any case, the only consequence is now that the
symlink type of those has to be specified via Git attributes, is all.
Reported-by: Justin Lee <jessdhoctor@gmail.com>
Addresses: CVE-2026-32631
Addresses: https://github.com/git-for-windows/git/security/advisories/GHSA-9j5h-h4m7-85hx
Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Every once in a while I need to verify that Microsoft Git's test suite
passes for changes that are not yet meant for public consumption, and
since it was (made) too difficult to keep up a working Azure Pipeline
definition, I have to use GitHub Actions in a private GitHub repository
for that purpose.
In these tests, basically all Dockerized CI jobs fail consistently. The
symptom is something like:
error: cannot create async thread: Resource temporarily unavailable
in the middle of a test, typically in the t5xxx-t6xxx range. The first
such error is immediately followed by plenty more of these errors, and
not a single test succeeds afterwards.
At first, I thought that maybe the massive parallelism I enjoy there is
the problem, and I thought that the cgroups limits might be shared
between the many containers that run on essentially the same physical
machine. But even reducing the matrix to just a single of those
Dockerized jobs runs into the very same problems.
The underlying reason seems to be a substantial difference in the hosted
runners that execute these Dockerized jobs: forcing the PID limit of the
container to a high number lets the jobs pass, even when running the
complete matrix of all 13 Dockerized jobs concurrently. But that's not
the only difference: The jobs seem to take a lot longer in these
containers than, say, in the containers made available to
https://github.com/git/git.
When forcing a PID limit of 64k in that private repository, the jobs
completed successfully, but they also took a lot longer, between 2x to
2.5x longer, i.e. painfully much longer. Reducing the PID limit to 16k,
the CI jobs still passed, but took an equally long amount of time.
Reducing the PID limit to 8k caused the errors to reappear.
Here are the numbers from three example runs, the first one forcing the
PID and nproc limit to 65536, the second one to 16384, the third run is
from the public git/git repository:
Job | 64k | 16k | reference
------------------------------|---------|---------|---------
almalinux-8 | 19m 3s | 16m 0s | 9m 36s
debian-11 | 20m 31s | 20m 3s | 8m 5s
fedora-breaking-changes-meson | 16m 29s | 19m 19s | 9m 40s
linux-asan-ubsan | 1h 10m | 1h 11m | 34m 36s
linux-breaking-changes | 25m 39s | 25m 58s | 13m 15s
linux-leaks | 1h 9m | 1h 10m | 33m 30s
linux-meson | 28m 9s | 27m 4s | 13m 45s
linux-musl-meson | 16m 32s | 13m 39s | 8m 6s
linux-reftable-leaks | 1h 13m | 1h 13m | 34m 34s
linux-reftable | 26m 2s | 25m 48s | 13m 31s
linux-sha256 | 26m 12s | 26m 3s | 12m 36s
linux-TEST-vars | 26m 5s | 25m 21s | 13m 25s
linux32 | 21m 16s | 19m 57s | 10m 44s
It does not look as if the PID limit is the reason for the longer
runtime, seeing as the 64k vs 16k timings deviate no more than as is
usual with GitHub workflows. So let's go for 16k.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
TortoiseGit actually compiles kind of a "libified" version of this,
where the `die()` calls are substituted with C++ `throw` constructs.
Therefore the (`static`, stays allocated even after returning from the
function) `realpath` actually _can_ be reused.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
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
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>
We lost ability to use https:// proxies during this cycle; this is
a hotfix for the regression.
* js/http-https-proxy-fix:
http: accept https:// proxies again
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>
Since 663d7abe07 (http: reject unsupported proxy URL schemes,
2026-05-05), set_curl_proxy_type() returns 0 only for the "http"
and SOCKS variants via dedicated early returns, and -1 for
everything else. The "https" branch configures the CURL handle for
HTTPS proxying but then falls through to the trailing `return -1`
intended for unknown schemes, so the caller in get_curl_handle()
treats a perfectly valid https:// proxy URL as unsupported and
refuses to use it.
Noticed while looking into a Coverity report against the same
function; the unchecked curl_easy_setopt() return values it flags
are orthogonal to this fix.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
While researching a build failure in `shears/seen`, I noticed that the
`vcpkg` Pipeline [has been broken since August last
year](https://dev.azure.com/git/git/_build?definitionId=9&_a=summary) 🤦.
The reason is that the `schannel` feature of `curl` was removed, as part
of https://github.com/microsoft/vcpkg/pull/46459. This PR did not remove
_Secure Channel support_, it merely removed the ability to specify it
_as a feature_. Let's accommodate for that.
vcbuild: stop hard-coding OpenSSL as a dependency
Git for Windows' default SSL backend is actually Secure Channel. Let's
not hard-code any backend, just ask for _any_ SSL backend.
This is necessary because we cannot ask for `schannel`, as
https://github.com/microsoft/vcpkg/pull/46459 removed the option to
specify that as a feature.
Signed-off-by: Dennis Ameling <dennis@dennisameling.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Add a "Preserving Quotation Marks" section to prevent AI-assisted
translation and review from incorrectly converting language-specific
UTF-8 curly quotes (e.g., „ U+201E, " U+201C for Bulgarian) into
ASCII straight quotes " (U+0022), which would cause PO string
truncation and syntax errors.
Also update the "Special characters" item in the Quality checklist
to reference the new section.
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>