When 6a29c2dfec ("mingw: use mimalloc",
2019-06-24) introduced the vendored mimalloc, the comparison was against
`nedmalloc` (which by then had not seen an upstream commit since 2014,
and whose repository was archived in 2019). The two were essentially at
parity in that benchmark; mimalloc was chosen because it was actively
developed. I do not really recall whether the platform's *default*
allocator was not part of the comparison; If it was, the performance was
still worse than mimalloc, if it wasn't, I forgot to test ;-)
Six years on, with `nedmalloc` safely on its way to being dropped from
the upstream codebase entirely
(https://github.com/gitgitgadget/git/pull/2104, currently in `seen` as
e576abb9f8), the question is no longer "mimalloc vs nedmalloc" but
"mimalloc vs the OS allocator". Re-running the same `git repack -adfq`
benchmark against each platform's current default allocator finds no
measurable speedup from mimalloc on any of Windows, macOS, or Linux.
## Methods
I recapitulated the same benchmark as cited in 6a29c2dfec (the original
comparison was nedmalloc vs mimalloc on `git repack -adfq` over a subset
of `linux.git`), now extended to the three GitHub-hosted runners
(`ubuntu-latest`, `macos-latest`, `windows-latest`). Each job built two
`git` binaries from the same source tree, vanilla and
`USE_MIMALLOC=YesPlease`, then prepared a fresh bare clone of
`linux.git` to a fixed `SHA`, and ran the repacks with both built `git`s
in randomized order for five iterations. Each iteration ran both
binaries exactly once on a freshly `copytree`-ed copy of the immutable
template repository; the order *within* an iteration was randomized so
any per-iteration confounder (cache state, runner warm-up, neighbour-VM
contention) would be shared symmetrically between variants. Timings
excluded the `copytree`. The full driver is the Python script
`ci/bench-mimalloc.py` on the [`mimalloc-benchmark`
branch](https://github.com/dscho/git/tree/mimalloc-benchmark/ci).
## Results: original `linux v2.6.20`-era workload (49,917 commits,
431,605 objects, ~204 MB pack)
| Platform | vanilla mean ± stdev | mimalloc mean ± stdev | Δ (mimalloc
− vanilla) |
|---|---|---|---|
| `ubuntu-latest` | 27.089s ± 0.060s | 27.041s ± 0.065s | −0.048s
(−0.18%) |
| `macos-latest` | 23.259s ± 1.206s | 25.076s ± 2.279s | +1.817s (+7.8%)
|
| `windows-latest` | 29.828s ± 1.651s | 30.329s ± 2.428s | +0.501s
(+1.7%) |
Workflow run: https://github.com/dscho/git/actions/runs/25374127848
## Results: 4x larger `linux v3.0` workload (255,039 commits, 2,059,429
objects, ~788 MB pack)
| Platform | vanilla mean ± stdev | mimalloc mean ± stdev | Δ (mimalloc
− vanilla) |
|---|---|---|---|
| `ubuntu-latest` | 134.723s ± **0.329s** | 134.801s ± **0.191s** |
+0.078s (+0.06%) |
| `macos-latest` | 130.183s ± 19.098s | 133.292s ± 18.991s | +3.109s
(+2.4%) |
| `windows-latest` | 145.183s ± 1.272s | 146.271s ± 4.161s | +1.088s
(+0.75%) |
Workflow run: https://github.com/dscho/git/actions/runs/25376885309
## Discussion
The Linux numbers on the larger workload are particularly clear: stdev
is below 0.3% of the mean for both variants, and the difference is well
inside that floor. Glibc's allocator and the vendored mimalloc are
statistically indistinguishable for `git repack -adfq` here.
`windows-latest` runners are noisier (per-run variance ~1-4%, mostly
neighbour-VM scheduling), but mimalloc never beats vanilla in either
workload. With the original justification for keeping a custom allocator
gone (the modern Windows segment-heap is no longer the slow
Windows-XP-era `HeapAlloc` that drove the original 2009 nedmalloc
adoption), there is nothing left to motivate the maintenance cost of a
vendored allocator.
`macos-latest` is too noisy at n=5 (stdev 14% of the mean) to draw a
firm conclusion, but the visible point-estimate goes the wrong way and
there is no plausible mechanism by which Apple's `libsystem_malloc`
would be slower than mimalloc.
## What this PR does *not* do
It does not by itself remove `nedmalloc` from the tree; that is still
promised as a follow-up of the in-flight upstream patch
https://github.com/gitgitgadget/git/pull/2104, presently in `seen` as
e576abb9f8. The first commit here is an `amend!` whose autosquashed
result is byte-identical to that upstream commit, so once the next
merging-rebase picks up the upstream patch the two will collapse
cleanly.
The five remaining `fixup!` reverts target each of the original
mimalloc-vendoring commits in reverse chronological order; once
autosquashed, the pairs cancel out to empty commits which the rebase
will drop, leaving the tree free of `compat/mimalloc/`, the
`USE_MIMALLOC` build infrastructure, and the supporting changes
(`compat/posix.h` `_DEFAULT_SOURCE` guard, `win32_pthread_*` renames)
that only existed to support the vendored allocator.
Part of the series that drops the vendored `mimalloc` from this fork;
the rationale (no measurable speedup over the platform allocator on
any of Windows, macOS, or Linux) is in the second commit of the
series and the PR description. The original commit was a preparation
step for vendoring `mimalloc` in (which forces C11 mode under
mingw-w64 GCC and so implicitly links libwinpthread, clashing with
Git's own emulation). With `mimalloc` gone the rename is no longer
needed, so this revert restores the plain `pthread_create` /
`pthread_self` names. The `fixup!` subject is so the next rebase
against an upstream Git that already lacks the target commit
autosquashes this revert into it, dropping the original cleanly.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Part of the series that drops the vendored `mimalloc` from this fork;
the rationale (no measurable speedup over the platform allocator on
any of Windows, macOS, or Linux) is in the second commit of the
series and the PR description. The `fixup!` subject is so the next
rebase against an upstream Git that already lacks the target commit
autosquashes this revert into it, dropping the original cleanly.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Part of the series that drops the vendored `mimalloc` from this fork;
the rationale (no measurable speedup over the platform allocator on
any of Windows, macOS, or Linux) is in the second commit of the
series and the PR description. The `fixup!` subject is so the next
rebase against an upstream Git that already lacks the target commit
autosquashes this revert into it, dropping the original cleanly.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Part of the series that drops the vendored `mimalloc` from this fork;
the rationale (no measurable speedup over the platform allocator on
any of Windows, macOS, or Linux) is in the second commit of the
series and the PR description. The `fixup!` subject is so the next
rebase against an upstream Git that already lacks the target commit
autosquashes this revert into it, dropping the original cleanly.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Re-running the `git repack -adfq` benchmark from
6a29c2dfec ("mingw: use mimalloc",
2019-06-24) against the platform's *current* default allocator (so
without `nedmalloc` in the picture at all) shows mimalloc is no longer
faster than the system allocator on any of Windows, macOS, or Linux,
neither for the original ~30-second `linux v2.6.20` workload nor for a
4x larger `linux v3.0` workload where each individual run takes ~2
minutes (and the noise floor on Linux is below 0.3% of the mean, so
even small differences would be visible if any existed).
`mimalloc` was originally chosen over nedmalloc, not over the system
allocator. Six years on, with nedmalloc now being dropped from the
codebase entirely, the allocator that mimalloc has to beat is whatever
the OS ships by default; modern Windows segment-heap, glibc malloc, and
the macOS libsystem allocator have all closed the gap, and there is no
longer a measurable benefit to keep maintaining a custom allocator.
The actual benchmark methodology, the per-platform numbers, and links
to the workflow runs that produced them are spelled out in the PR
description rather than repeated across each fixup.
The `fixup!` subject is so that the next rebase against an upstream
Git that already lacks this commit will autosquash this revert into
the original (which becomes empty and is dropped), leaving the tree
free of `mimalloc`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
mingw: stop using nedmalloc
The vendored nedmalloc allocator under compat/nedmalloc/ has been
unmaintained upstream for a very long time: the original repository at
https://github.com/ned14/nedmalloc received its last commit on July 5,
2014, and was archived (made read-only) by its owner on March 15, 2019.
Our copy has been carried forward unchanged ever since.
The Git for Windows commit that introduced mimalloc as a replacement
on Windows ("mingw: use mimalloc", 2019-06-24, present in the Git for
Windows branch thicket but not upstream) already observed at that time
that nedmalloc had ceased to see any updates for several years.
This came to a head when the Git for Windows SDK upgraded to GCC 16:
the `add_segment()` function in `compat/nedmalloc/malloc.c.h` declares
`int nfences = 0` and only references it inside an `assert()`, which
GCC 16 now flags as `-Wunused-but-set-variable`. Combined with the
`-Werror` enabled by `DEVELOPER=1`, this turns into a hard build
failure:
compat/nedmalloc/malloc.c.h: In function 'add_segment':
compat/nedmalloc/malloc.c.h:3897:7: error: variable 'nfences' set but not used [-Werror=unused-but-set-variable=]
3897 | int nfences = 0;
| ^~~~~~~
cc1.exe: all warnings being treated as errors
The same source built without complaint under GCC 15.2.0; the
regression was bisected to the SDK package update at
https://github.com/git-for-windows/git-sdk-64/commit/188d93dd455
(`mingw-w64-x86_64-gcc 15.2.0-14 -> 16.1.0-1`), with the failing CI
run captured at
https://github.com/git-for-windows/git-sdk-64/actions/runs/25244795074.
Rather than patch the unmaintained vendored sources to silence the
warning, stop opting into nedmalloc altogether on MINGW. The platform
allocator is what every non-MINGW build already uses, and a fresh
build of git.git's master against a minimal Git for Windows SDK
upgraded to GCC 16, with `USE_NED_ALLOCATOR` removed from the MINGW
section, completes successfully.
The compat/nedmalloc/ subtree itself is left in place to keep this
change minimal; nothing in the build links against it any longer, so
it can be removed in a follow-up if desired.
Assisted-by: Claude Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This closes two gaps in the current `AGENTS.md` that came up while
drafting #6231 and #2104:
1. The `Fixup Commits` section only covered `fixup!`. `amend!` has
different semantics (replaces the target's commit message and combines
diffs to produce any final state), and the "amend! whose body is the
upstream commit and whose diff aligns the squashed result with that
upstream commit" pattern is precisely how the first commit of #6231
anticipates the in-flight nedmalloc removal in `seen` as `e576abb9f8`.
That pattern is undocumented today.
2. There is no top-level "Contributing to Git for Windows" section, only
"Contributing to Upstream Git via GitGitGadget". The cross-fork `gh pr
create` invocation, the conditions under which a PR is naturally a
fixup/amend-only series against existing thicket commits, and the
upstream-aligning `amend!` shape were all things I inferred from context
rather than the guide.
Add subsections that cover those gaps. Nothing in the existing text
changes.
The `linux-{asan-ubsan,sha256,reftable}` jobs run inside
`ubuntu:rolling`, which now resolves to Ubuntu 26.04 with glibc 2.43;
that pulls `_Generic` into `<sys/cdefs.h>` and breaks our `-std=gnu99
-Werror` Clang builds. Concrete failure:
https://github.com/git-for-windows/git/actions/runs/25390480083/job/74463338845.
Picking up Patrick Steinhardt's fix from
https://lore.kernel.org/git/20260505-b4-pks-ci-tolerate-glibc-generic-v1-1-5786386fe512@pks.im/
ahead of its upstream merge so the GfW CI goes green again. The diff
conflicts with `fe5704a3695c "mimalloc: offer a build-time option to
enable it"`, which wraps the affected `config.mak.dev` block in `ifndef
USE_MIMALLOC`; the resolution preserves that wrap on the `gcc6`-only
branch surviving Patrick's patch. `meson.build` auto-merged.
When building with `make DEVELOPER=1` we explicitly pass "-std=gnu99" to
the compiler so that we don't start leaning on features exposed by more
recent versions of the C standard. Unfortunately though, glibc 2.43
started to use type-generic expressions. This works alright with GCC,
but when compiling with Clang this leads to errors:
$ make DEVELOPER=1 CC=clang
CC daemon.o
In file included from daemon.c:3:
./git-compat-util.h:344:11: error: '_Generic' is a C11 extension [-Werror,-Wc11-extensions]
344 | return !!strchr(path, '/');
| ^
/usr/include/string.h:265:3: note: expanded from macro 'strchr'
265 | __glibc_const_generic (S, const char *, strchr (S, C))
| ^
/usr/include/x86_64-linux-gnu/sys/cdefs.h:838:3: note: expanded from macro '__glibc_const_generic'
838 | _Generic (0 ? (PTR) : (void *) 1, \
| ^
In theory, the `__glibc_const_generic` macro does have feature gating:
#if !defined __cplusplus \
&& (__GNUC_PREREQ (4, 9) \
|| __glibc_has_extension (c_generic_selections) \
|| (!defined __GNUC__ && defined __STDC_VERSION__ \
&& __STDC_VERSION__ >= 201112L))
# define __HAVE_GENERIC_SELECTION 1
#else
# define __HAVE_GENERIC_SELECTION 0
#endif
But this feature gating isn't effective because `_has_extension()` will
always evaluate to true as C generics _are_ available as a language
extension to GNU C99 when using Clang. This would have been different if
`_has_feature()` was used instead, in which case it would have properly
evaluated to `false`.
Unfortunately, there is no easy way for us to work around the warning.
We cannot define `__HAVE_GENERIC_SELECTION` ourselves as that would lead
to a redefinition, and given that the conditions are or'd together we
cannot disable any of those, either.
Instead, work around the issue by not using -std=gnu99 with Clang when
using the Makefile and by disabling warnings about C11 extensions when
using Meson. This isn't ideal, but we at least retain the ability to
detect the (mis-)use of features from newer standards with GCC.
An alternative to this might be to simply bump the required C standard
to C11, which is 15 years old by now and should have support on most
platforms out there. But some more esoteric platforms may not have it.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The existing `Fixup Commits` section explained the `fixup!` flavour
but said nothing about `amend!`, which has different semantics
(replaces the target's commit message and combines diffs to produce
any desired final state). The `amend!` form is also the canonical
way to align a downstream branch-thicket commit with an in-flight
upstream replacement, so its absence from the guide left a hole that
contributors fill by reading the merging-rebase machinery from
source.
Add a dedicated subsection covering `amend!`, plus a separate
subsection on the pattern of constructing PRs that consist *only* of
`fixup!` and `amend!` commits targeting existing thicket commits.
That pattern is the natural shape for a PR that adjusts or removes a
multi-commit downstream feature: each pair autosquashes during the
next merging-rebase, exact-cancel pairs drop as empty, and the end
state is as if the originals had been edited or removed in place.
Also add a top-level `Contributing to Git for Windows` section to
parallel the existing `Contributing to Upstream Git via GitGitGadget`
section, with the cross-fork `gh pr create` invocation, a pointer to
when the fixup-and-amend-only shape is appropriate, and a pointer to
when the upstream-aligning `amend!` pattern is appropriate. Until
now the guide covered upstream contributions in detail but said
nothing about the primary contribution path for this fork.
Assisted-by: Claude Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Bump actions/checkout from v5 to v6 and
git-for-windows/setup-git-for-windows-sdk from v1 to v2.
Both bumps are Node.js 20 to Node.js 24 runtime migrations with
no functional changes to the actions themselves. checkout v6 moves
persisted credentials to `` instead of `.git/config`,
which does not affect this workflow since no subsequent steps rely
on the credential location. The setup-sdk v2 provisions the same
minimal SDK as v1.
Risk: very low. The only precondition is a recent Actions Runner,
which github.com-hosted runners already satisfy.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The l10n workflow uses `mshick/add-pr-comment` to post git-po-helper
reports as comments on translation pull requests. It was still pinned
to v2, which runs on Node.js 20. GitHub is phasing out the Node.js 20
runtime on Actions runners, so staying on v2 will eventually cause the
"Create comment in pull request for report" step to fail.
The sole breaking change in v3 is the switch from Node.js 20 to
Node.js 24 (https://github.com/mshick/add-pr-comment/releases/tag/v3.0.0).
The action's inputs and outputs are unchanged, so the upgrade is a
drop-in replacement. Subsequent v3.x releases added new opt-in
features (message truncation, retry with exponential backoff, file
attachments, commit comment support, "delete on status") but none of
them affect existing callers that do not opt in.
See also:
- Changelog: https://github.com/mshick/add-pr-comment/blob/main/CHANGELOG.md
- Compare: https://github.com/mshick/add-pr-comment/compare/v2...v3
Pointed-out-by: Christoph Grüninger <foss@grueninger.de>
Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The v1 of `git-for-windows/setup-git-for-windows-sdk` runs on
Node.js 20, which GitHub is phasing out of the Actions runners.
v2 moves the action to Node.js 24 so that the CI jobs relying on
a Git for Windows SDK keep working once Node.js 20 is removed.
The risk is very low: v2 contains no functional changes to the
SDK setup itself, only the runtime upgrade. The action still
provisions the same minimal SDK and exposes the same outputs.
The sole precondition is a recent Actions Runner (>= 2.327.1),
which the github.com-hosted runners already satisfy.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This PR is a companion of https://github.com/gitgitgadget/git/pull/2103.
On Windows, `maintenance_task_geometric_repack()` opens pack index files
via `pack_geometry_init()` (which `mmap()`s the `.idx` files), then
spawns `git repack` as a child process without setting
`child.odb_to_close`. The parent's `mmap()`s prevent the child from
deleting old `.idx` files.
On Windows 10 builds before the POSIX delete semantics change (between
Build 17134.1304 and 18363.657, see
https://stackoverflow.com/a/60512798), this results in `Unlink of file
'.git/objects/pack/pack-<hash>.idx' failed. Should I try again?` during
fetch-triggered auto-maintenance with the geometric strategy.
The fix adds the missing `child.odb_to_close = the_repository->objects`
line, matching all other maintenance tasks.
The first commit introduces a `GIT_TEST_LEGACY_DELETE` environment
variable to simulate legacy (pre-POSIX) delete semantics on modern
Windows, so the regression test can verify the fix even on Windows 11.
This fixes https://github.com/git-for-windows/git/issues/6210.
Tested-by: Patryk Miś <foss@patrykmis.com>
As is done for all the other maintenance tasks, let's release the ODB
also before starting the geometric repacking. That way, the `.idx` files
won't be `mmap()`ed when they are to be deleted (which does not work on
Windows because you cannot delete files on that platform as long as they
are kept open by a process).
This regression was introduced by 9bc151850c (builtin/maintenance:
introduce "geometric-repack" task, 2025-10-24), but was only noticed
once geometric repacking was made the default in 452b12c2e0 (builtin/
maintenance: use "geometric" strategy by default, 2026-02-24).
The fix recapitulates my work from df76ee7b77f0 (run-command: offer to
close the object store before running, 2021-09-09) & friends.
To guard against future regressions of this kind, add a check to
`run_and_verify_geometric_pack()` in `t7900` that detects orphaned
`.idx` files left behind after repacking. Contrary to interactive
calls, the `git maintenance` call in that test case would _not_ block on
Windows, asking whether to retry deleting that file, which is the reason
why this bug was not caught earlier.
Furthermore, since the default behavior of `DeleteFileW()` was changed
at some point between Windows 10 Build 17134.1304 and Build 18363.657
to use POSIX semantics (see https://stackoverflow.com/a/60512798),
the added orphaned-`.idx` check would be insufficient to catch this
regression on modern Windows without emulating legacy delete semantics
via `GIT_TEST_LEGACY_DELETE=1`.
This fixes https://github.com/git-for-windows/git/issues/6210.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
At some point between Windows 10 Build 17134.1304 and Build 18363.657,
the default behavior of `DeleteFileW()` was changed to use POSIX
semantics (https://stackoverflow.com/a/60512798). Under those semantics,
a file can be deleted even when another process holds an active
`MapViewOfFile` view on it: the directory entry is removed immediately,
but the underlying data persists until the last handle is closed.
On older Windows versions (and Windows 10 builds before that change),
`DeleteFileW()` uses legacy semantics where deletion fails outright if
any process holds a file mapping.
To allow testing code paths that depend on the legacy behavior, introduce
a `GIT_TEST_LEGACY_DELETE` environment variable. When set, `mingw_unlink()`
uses `SetFileInformationByHandle()` with `FileDispositionInfo` (the
non-POSIX variant) instead of `DeleteFileW()`, forcing legacy delete
semantics regardless of the Windows version.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Over time, as upstream Git absorbs fixes and features that originated in
or were carried by Git for Windows, downstream patches accumulate that
are no longer needed. The steady stream of merged PRs makes this
virtually inevitable. This PR collects fixup! commits to drop three such
patches during the next autosquash rebase.
The HTTP/2 workaround in `t5551` was a temporary fix for a libcurl
v8.10.0 regression on macOS CI runners. The faulty libcurl has long been
superseded by fixed versions, making it unnecessary.
The `unix-socket: avoid leak when initialization fails` patch changed
`return -1` to `goto fail` in `unix_stream_connect()` so cleanup would
run when `unix_sockaddr_init()` failed. Upstream fixed the same leak
more surgically in c5fe29f696 (unix-socket: fix memory leak when
chdir(3p) fails, 2025-01-30) by having `unix_sockaddr_init()` call
`FREE_AND_NULL(ctx->orig_dir)` before returning, making the downstream
caller-side fix redundant.
The `revision: create mark_trees_uninteresting_dense()` commit was a
preparatory patch for the path-walk API. That API has since been
upstreamed, and this commit became empty during the merging-rebase
because its changes were already in the new base.
This was a preparatory commit for the path-walk API, which has since
been upstreamed into v2.54.0. During the merging-rebase, the code
changes this commit introduced were already present in the new base,
leaving it empty. Drop it.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This was marked as a temporary work-around in 4538ee661d (ci: work
around a problem with HTTP/2 vs libcurl v8.10.0 (#5165), 2024-09-24), to
help CI builds pass even on macOS. The faulty libcurl version has hence
been replaced with plenty of fixed ones, therefore this work-around is
no longer necessary.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
AI-assisted contributions are a reality of open source in 2025 and
beyond. Contributors will use AI tools, and that includes the
maintainers themselves. Over recent months, I have found AI increasingly
useful for the kind of menial, tedious work that does not require much
creativity but is highly boring when done by hand: resolving merge
conflicts during merging-rebases, chasing down CI failures across
platforms, adapting downstream patches to upstream API changes.
To that end, I would like to have an `AGENTS.md` file in the code base
that helps any LLM to understand the context of the project.
A secondary goal of this is to preemptively help outside contributors.
The risk is not AI usage per se, but low-quality AI slop: contributions
where the human hits "accept" without sufficient context being available
to the model (and without proper review by the human, we've all been
there), resulting in changes that miss conventions, break patterns, or
misunderstand the project's architecture. Git's source code is about as
legacy as they come, having grown organically over two decades with no
design that AI coding models would readily grasp from a narrow code
sample alone.
This `AGENTS.md` is designed to raise the floor on AI-assisted
contributions by providing enough context that even when a human
contributor fails to steer carefully, the model has the information it
needs to produce something reasonable. It documents the repository
structure, build process, test conventions, the object model and ODB
internals, debugging techniques (Trace2, instrumenting tests, bisecting
failures), the merging-rebase workflow, conflict resolution patterns,
coding conventions (ASCII only, 80 columns, tabs), commit message
expectations, and the GitGitGadget contribution workflow. This is
information that a human might take for granted, but no coding model
will have been trained on specifically.
Similar `AGENTS.md` files have recently been added to other repositories
in the Git for Windows project:
[MINGW-packages](https://github.com/git-for-windows/MINGW-packages/pull/194),
[git-for-windows.github.io](https://github.com/git-for-windows/git-for-windows.github.io/pull/88)
and
[msys2-runtime](1e0ff37207).
AGENTS: document learnings from split-index + fsmonitor investigation
While investigating a CI failure in the `linux-TEST-vars` job caused by
the interaction between the `pt/fsmonitor-linux` and
`hn/git-checkout-m-with-stash` topics in `seen`, several debugging
techniques proved essential and were not previously documented.
The investigation required bisecting the first-parent history of `seen`
while temporarily merging the fsmonitor topic at each step. This
revealed that `GIT_TEST_SPLIT_INDEX=yes` corrupts the bisect
machinery's own index operations unless it is unset before cleanup
checkouts. It also revealed that `fprintf(stderr, ...)` instrumentation
in Git's C code is swallowed by the test framework, making Trace2 the
correct instrumentation approach.
A key insight was that the bug appeared Linux-specific only because
`linux-TEST-vars` is the sole CI job setting `GIT_TEST_SPLIT_INDEX=yes`;
there is no macOS or Windows equivalent. The actual root cause (the
`index.skipHash=true` + split-index interaction producing a null
`base_oid` in the shared index) is platform-independent.
Add four documentation sections capturing these learnings: bisecting
`seen` interactions, reproducing with exact CI variables, verifying CI
platform coverage before concluding platform-specificity, and using
Trace2 for instrumentation inside the test framework.
Assisted-by: Claude Opus 4.6
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
AGENTS.md: add pre-commit checklist for lint checks
Bundle the existing ASCII-only, 80-column, and whitespace validation
recipes into a "pre-commit checklist" block that agents should run
before every commit. The individual recipes already existed in the
Coding Conventions section but were presented as reference material
rather than as an actionable workflow step.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Assisted-by: Claude Opus 4.6
AGENTS.md: document rebase, staging, and log -L tricks for AI agents
Add practical recipes for three workflows that are particularly useful
when AI agents work with Git:
Non-interactive "interactive" rebases using `sed -i 1ib` as a sequence
editor to insert a `break` command, then editing the todo file directly
via the path from `git rev-parse --git-path rebase-merge/git-rebase-todo`.
This avoids the impossible task of driving an interactive editor from an
AI agent.
Scripted hunk staging via `printf '%s\n' s y q | git add -p`, which
feeds predictable keystrokes to the add-patch protocol to stage
individual hunks without human interaction.
The `git log -L <start>,+<count>:<file>` trick for finding which commit
last touched specific lines, enabling an `hg absorb`-like workflow where
the agent can identify the right fixup! target surgically rather than
grepping through full diffs.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Assisted-by: Claude Opus 4.6
AGENTS.md: add upstream contribution and worktree guidance
Add sections covering the GitGitGadget workflow for contributing to
upstream Git, commit message conventions specific to the upstream
project, how to manage patch series with dependencies (branch
thickets), effective worktree usage including --update-refs for
history rewrites, and techniques for analyzing merge-structured
topic branches with git replay.
These learnings come from a session contributing the
safe.bareRepository test preparation patches via GitGitGadget.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Assisted-by: Claude Opus 4.6
This adds an extensive section about resolving merge conflicts during
rebases, which happens quite often in Git for Windows' day-to-day.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
In this time and age, AI is everywhere. However, it's sometimes not very
easy to use. For green-field projects it works quite a bit better than
for existing legacy projects. And Git's source code is _quite_ as legacy
code as they come... 😁
Now, the only way how AI can be used efficiently with legacy code
is by providing enough information by way of prompt context for the
AI to have a chance to make any sense of the code. The structure and
the architecture is, after all, not designed for AI, but rather the
opposite: By virtue of having grown organically over two decades, there
is no design that AI coding models would readily grasp.
So here is a document that describes all kinds of aspects about this
project. The idea is to help AI by providing information that it does
not have ingrained in its weights. The idea is to provide information
that a human prompter might take for granted, but no coding model will
have been trained on specifically.
Assisted-by: Claude Opus 4.5
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Every workflow currently pins `actions/checkout` to v5, which was
introduced primarily to move to the Node.js 24 runtime. v6 is the
next release and worth picking up so we stay on a maintained version
of the action.
The one behaviorally interesting change in v6:
`persist-credentials` now stores the helper credentials under
`$RUNNER_TEMP` instead of writing them directly into the local
`.git/config`. Two implications follow:
1. In the normal case this is an unambiguous improvement -- the
token no longer lands in `.git/config`, reducing the risk of
inadvertently leaking it through workspace archiving
(`upload-artifact` snapshots, cache entries, core dumps, ...).
2. Docker container actions require an Actions Runner of at least
v2.329.0 to find the credentials in their new location. The
github.com-hosted runners our CI uses are already past that
version, so this does not affect us. Downstream users running
self-hosted runners may need to update them before adopting
this version of the action.
Risk analysis: our checkout steps either check out the default
repository (no special credential requirements) or, in the `vs-build`
job, explicitly set `repository: microsoft/vcpkg` and
`path: compat/vcbuild/vcpkg`. Neither case relies on the precise
location of the persisted credentials -- subsequent steps interact
with the API via the runner-provided `GITHUB_TOKEN` directly -- so
the v6 credential-storage change is transparent to our workflows.
The diff is purely the `@vN` identifier; there are no input or
output changes.
See also:
- Release notes: https://github.com/actions/checkout/releases
- Changelog: https://github.com/actions/checkout/blob/main/CHANGELOG.md
- Compare: https://github.com/actions/checkout/compare/v5...v6
Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The only use we have of `actions/github-script` is the "skip if the
commit or tree was already tested" step in `main.yml`, which checks
whether an identical tree-SHA was already built successfully. It
currently pins v8; v9 is the latest release.
What v9 changes:
- The `ACTIONS_ORCHESTRATION_ID` environment variable is now
appended to the HTTP user-agent string. This is transparent to
our script.
- A new injected `getOctokit` factory lets scripts create
additional authenticated clients in the same step without
importing `@actions/github`. We do not use it.
- Two breaking changes affect scripts that either call
`require('@actions/github')` (fails at runtime, because
`@actions/github` v9 is now ESM-only) or that shadow the
implicit `getOctokit` parameter via `const`/`let` (syntax
error). Our script does neither -- it only uses the pre-supplied
`github` REST client and `core` helpers -- so the upgrade is
safe.
Risk analysis: the step is advisory. It sets `enabled=' but skip'`
as an optimization to avoid re-running CI on a tree that was already
tested successfully. Even if the v9 upgrade broke the script, the
surrounding `try { ... } catch (e) { core.warning(e); }` block would
degrade it to a warning and CI would still run normally. In practice
the script continues to work identically on v9.
See also:
- Release notes: https://github.com/actions/github-script/releases
- Compare: https://github.com/actions/github-script/compare/v8...v9
Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
`actions/upload-artifact` and `actions/download-artifact` are tightly
coupled: the upload action writes artifact archives in a format that
the download action then reads. Because of this coupling, the two
actions should always be bumped together so that the artifact format
contract between them is satisfied.
All of our `actions/upload-artifact` uses are still on v5, with one
stray v4 occurrence. Keeping them on these versions would leave the
artifact-upload steps running on Node.js 20, which GitHub is phasing
out, and would eventually cause all upload steps to fail.
Going from v5 directly to v7 folds in two release bumps:
- v6 switches the action's default runtime from Node.js 20 to
Node.js 24 (v5 had preliminary Node 24 support but still defaulted
to Node 20). This is the main motivation for bumping now: it gets
us off the deprecated runtime.
- v7 adds two opt-in features: direct (unzipped) single-file uploads
via a new `archive: false` parameter, and an internal conversion of
the action to ESM to match the updated `@actions/*` packages.
Risk analysis: we never pass `archive`, so the zip-as-usual behavior
is unchanged. We also do not `require('@actions/*')` from any calling
workflow, so the ESM migration cannot affect us. The upload steps we
care about -- tracked files/build artifacts and failing-test
directories -- keep the same inputs (`name`, `path`) and outputs, so
the diff is purely the `@vN` identifier. The main precondition is a
recent Actions Runner (>= 2.327.1), which the github.com-hosted
runners used by our CI already satisfy.
While at it, align the one remaining `@v4` occurrence with the rest
so that every `upload-artifact` step uses the same version.
See also:
- Release notes: https://github.com/actions/upload-artifact/releases
- Compare: https://github.com/actions/upload-artifact/compare/v5...v7
We use `actions/download-artifact` to pass build artifacts between
the "windows-build" / "vs-build" / "windows-meson-build" jobs and
their corresponding test jobs. All callers are currently on v6;
bumping to v8 keeps this action in lockstep with the `upload-artifact`
bump above.
What v7 and v8 change:
- v7 switches the default runtime from Node.js 20 to Node.js 24 (v6
had preliminary Node 24 support but still defaulted to Node 20).
This is the main motivation: it gets us off the deprecated runtime.
- v8 makes three further changes:
* The package is converted to ESM (invisible to workflow authors).
* The action now checks the `Content-Type` header before
attempting to unzip a download, so that directly-uploaded
(unzipped) artifacts from `upload-artifact` v7 are downloaded
correctly.
* The `digest-mismatch` behaviour is changed from warn-and-
continue to a hard failure by default.
Risk analysis: defaulting hash-mismatch to a hard failure is
strictly safer than the previous warn-and-continue behaviour -- a
mismatch points to real corruption or tampering and should stop the
run. We download archives that the same workflow just uploaded, on
the same runner fleet, so false positives are not expected. Our
usage is limited to the `name` and `path` inputs, which are
unchanged between v6 and v8, so the diff is purely the `@vN`
identifier.
See also:
- Release notes: https://github.com/actions/download-artifact/releases
- Compare: https://github.com/actions/download-artifact/compare/v6...v8
Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The v2 of `microsoft/setup-msbuild` runs on Node.js 20, which GitHub
is phasing out of the Actions runners. v3 is a minimal release whose
only substantive change is moving the action's runtime to Node.js 24,
so that our Visual Studio build jobs keep working once Node.js 20 is
removed from the runners.
The risk of this bump is very low: v3 contains no functional changes
to the action itself -- it merely adds `msbuild.exe` to `PATH`, with
no change to command-line flags, inputs, outputs, or default tool
resolution. The only precondition is a recent-enough Actions Runner,
which the github.com-hosted runners already satisfy.
See also:
- Release notes: https://github.com/microsoft/setup-msbuild/releases
- Compare: https://github.com/microsoft/setup-msbuild/compare/v2...v3
Originally-authored-by: dependabot[bot] <support@github.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Originally introduced as `core.useBuiltinFSMonitor` in Git for Windows
and developed, improved and stabilized there, the built-in FSMonitor
only made it into upstream Git (after unnecessarily long hemming and
hawing and throwing overly perfectionist style review sticks into the
spokes) as `core.fsmonitor = true`.
In Git for Windows, with this topic branch, we re-introduce the
now-obsolete config setting, with warnings suggesting to existing users
how to switch to the new config setting, with the intention to
ultimately drop the patch at some stage.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This topic branch re-adds the deprecated --stdin/-z options to `git
reset`. Those patches were overridden by a different set of options in
the upstream Git project before we could propose `--stdin`.
We offered this in MinGit to applications that wanted a safer way to
pass lots of pathspecs to Git, and these applications will need to be
adjusted.
Instead of `--stdin`, `--pathspec-from-file=-` should be used, and
instead of `-z`, `--pathspec-file-nul`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
A fix for calling `vim` in Windows Terminal caused a regression and was
reverted. We partially un-revert this, to get the fix again.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This patch introduces support to set special NTFS attributes that are
interpreted by the Windows Subsystem for Linux as file mode bits, UID
and GID.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This is the recommended way on GitHub to describe policies revolving around
security issues and about supported versions.
Helped-by: Sven Strickroth <email@cs-ware.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
With this patch, Git for Windows works as intended on mounted APFS
volumes (where renaming read-only files would fail).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Git for Windows accepts pull requests; Core Git does not. Therefore we
need to adjust the template (because it only matches core Git's
project management style, not ours).
Also: direct Git for Windows enhancements to their contributions page,
space out the text for easy reading, and clarify that the mailing list
is plain text, not HTML.
Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>