From 415958b7928d915edbf8041661e86f040b61f566 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Thu, 10 Sep 2026 11:20:14 +0100 Subject: [PATCH 1/5] rust: respect CARGO_BUILD_TARGET when locating build output When cross-compiling, Cargo always writes to a target-tuple subdirectory determined by CARGO_BUILD_TARGET, even when it matches the native tuple. The build looked in $BUILD_DIR/$BUILD_TYPE directly, so it failed to locate the freshly built library. Respect CARGO_BUILD_TARGET in the output path so the correct artifact is located. Signed-off-by: James Le Cuirot Signed-off-by: Junio C Hamano --- Makefile | 2 +- src/cargo-meson.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index d4b775953d3842..f0ca2e4f726ea8 100644 --- a/Makefile +++ b/Makefile @@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib else RUST_LIB_NAME = libgitcore.a endif -RUST_LIB = target/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME) +RUST_LIB = target/$(if $(CARGO_BUILD_TARGET),$(CARGO_BUILD_TARGET)/)$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME) endif GITLIBS = common-main.o $(LIB_FILE) diff --git a/src/cargo-meson.sh b/src/cargo-meson.sh index 75f3cd12654037..83c7e7b79b9d6f 100755 --- a/src/cargo-meson.sh +++ b/src/cargo-meson.sh @@ -38,7 +38,7 @@ then exit $RET fi -if ! cmp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1 +if ! cmp "$BUILD_DIR/${CARGO_BUILD_TARGET:+$CARGO_BUILD_TARGET/}$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1 then - cp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" + cp "$BUILD_DIR/${CARGO_BUILD_TARGET:+$CARGO_BUILD_TARGET/}$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" fi From ce6f9ffaa7e2882d0ebda143f8ac2c307782af8a Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 13 Sep 2026 15:57:11 +0000 Subject: [PATCH 2/5] rust: pick a GCC-compatible Cargo target under MSYS2/MinGW When Git is built under MSYS2/MinGW with Rust support enabled, the Makefile expects `cargo build` to drop a `target/release/libgitcore.a` that is linkable by the same MinGW GCC used for every other object. With Rust installed via `rustup` (the way it ships on the GitHub-hosted `windows-2022` and `windows-11-arm` runners that build git/git and its forks), the default toolchain targets the MSVC ABI; cargo then writes `target/release/gitcore.lib` instead, which the MinGW `ld.exe` cannot consume: LINK git-shell.exe D:\git-sdk-64-minimal\mingw64\bin/ld.exe: cannot find target/release/libgitcore.a: No such file or directory collect2.exe: error: ld returned 1 exit status See https://github.com/microsoft/git/actions/runs/27341625000 for a full example log. Let's define the correct target, using the `CARGO_BUILD_TARGET` variable that will be picked up by Rust, see https://dirname.github.io/rust-std-doc/cargo/reference/environment-variables.html#:~:text=CARGO%5FBUILD%5FTARGET Re-use (and fix) the existing `HOST_CPU` variable to determine the correct value. Avoid relying on environment variables that are simply not defined in Git for Windows' minimal SDK that Git uses in its CI runs. Assisted-by: Claude Opus 4.7 Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Makefile | 2 +- config.mak.uname | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fac3e8879c8377..ad1ba26f91e921 100644 --- a/Makefile +++ b/Makefile @@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib else RUST_LIB_NAME = libgitcore.a endif -RUST_LIB = target/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME) +RUST_LIB = target$(if $(CARGO_BUILD_TARGET),/$(CARGO_BUILD_TARGET))/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME) endif GITLIBS = common-main.o $(LIB_FILE) diff --git a/config.mak.uname b/config.mak.uname index 0b63be10b7782e..f3f3bcc4efbf3e 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -758,7 +758,30 @@ ifeq ($(uname_S),MINGW) MINGW_PREFIX := /$(shell echo '$(MSYSTEM)' | tr A-Z a-z) endif prefix = $(MINGW_PREFIX) - HOST_CPU = $(patsubst %-w64-mingw32,%,$(MINGW_CHOST)) + + # A rustup-managed Rust on Windows defaults to the MSVC ABI and + # produces a `gitcore.lib` that the MinGW `ld.exe` cannot link. + # Pick a GCC-compatible Rust target triple matching the MSYS2 + # subsystem instead: `*-pc-windows-gnullvm` for the Clang/LLVM + # subsystems (which on Windows is also the only choice for + # ARM64, where no MinGW-GCC port exists) and `*-pc-windows-gnu` + # for the MSVCRT-based MinGW subsystems. For a `staticlib` + # crate-type Cargo does not invoke an external linker, so + # `rustup target add ` is sufficient. + ifneq (,$(filter %ARM64, $(MSYSTEM))) + HOST_CPU = aarch64 + else ifneq (,$(filter %32, $(MSYSTEM))) + HOST_CPU = i686 + else + HOST_CPU = x86_64 + endif + ifneq (,$(filter CLANG%, $(MSYSTEM))) + CARGO_BUILD_TARGET = $(HOST_CPU)-pc-windows-gnullvm + else + CARGO_BUILD_TARGET = $(HOST_CPU)-pc-windows-gnu + endif + export CARGO_BUILD_TARGET + BASIC_LDFLAGS += -Wl,--pic-executable COMPAT_CFLAGS += -DDETECT_MSYS_TTY \ -DENSURE_MSYSTEM_IS_SET="\"$(MSYSTEM)\"" \ From 86909a94db5d29b2277bfc54331801199cf3ccaf Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 13 Sep 2026 15:57:12 +0000 Subject: [PATCH 3/5] ci(windows): build with Rust The Windows runners used by Git's GitHub workflow's `windows-build` job ship `rustup` plus a `*-pc-windows-msvc` default toolchain (see https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md and https://github.com/actions/partner-runner-images/blob/main/images/arm-windows-11-image.md), but no precompiled `std` for `*-pc-windows-gnu` or `*-pc-windows-gnullvm`. With the Makefile now picking a GCC-compatible target triple based on `$(MSYSTEM)`, the build step needs that precompiled `std` to be installed before invoking `make`, otherwise `cargo build --target ` fails to find a usable `std` for the chosen target. Add a step between the SDK setup and the `make` invocation that selects the matching triple from `$MSYSTEM` (which `git-for-windows/setup-git-for-windows-sdk` exports for every subsequent step) and runs `rustup target add` for it. The mapping mirrors what `config.mak.uname` derives from `$(MSYSTEM)` and `$(HOST_CPU)`, just enumerated explicitly here since CI has direct knowledge of which MSYS2 subsystems the matrix actually exercises (`CLANGARM64` for the ARM64 runner, `MINGW64` for the x86_64 runner). Technically, we only need to handle MINGW64 at present, but the switch to UCRT64 is imminent, and the other case arms serve as a very fine documentation of what people should do for other MSYSTEM values. For a `staticlib` crate-type `cargo build` does not invoke an external linker, so no further toolchain components (e.g. the `gnullvm` LLVM linker) need to be installed; `rustup target add` alone is sufficient. Assisted-by: Claude Opus 4.7 Helped-by: Junio C Hamano Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- .github/workflows/main.yml | 24 ++++++++++++++++++++++++ ci/lib.sh | 3 --- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 85cfedf5b0e0a4..09725473957154 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -114,6 +114,30 @@ jobs: steps: - uses: actions/checkout@v6 - uses: git-for-windows/setup-git-for-windows-sdk@v2 + - name: Install GCC-compatible Rust target + shell: bash + run: | + # The hosted Windows runners ship a rustup-managed Rust whose + # default toolchain targets the MSVC ABI. That produces a + # `gitcore.lib` which the MinGW GCC used by the rest of the + # build cannot link. Install the precompiled `std` for a + # GCC-compatible target triple matching the MSYS2 subsystem; + # the Makefile selects the same triple via $(MSYSTEM) and + # passes it to `cargo build --target`. + case "$MSYSTEM" in + CLANGARM64) target=aarch64-pc-windows-gnullvm ;; + CLANG64) target=x86_64-pc-windows-gnullvm ;; + CLANG32) target=i686-pc-windows-gnullvm ;; + UCRT64) target=x86_64-pc-windows-gnu ;; + MINGW64) target=x86_64-pc-windows-gnu ;; + MINGW32) target=i686-pc-windows-gnu ;; + *) echo "::error::Unsupported MSYSTEM: $MSYSTEM"; exit 1 ;; + esac && + rustup target add "$target" && + + # Ensure that cargo.exe is found even with the minimal SDK's restricted PATH + CARGO="$(type -p cargo.exe)" && + echo "export PATH=\$PATH:${CARGO%/cargo.exe}" >>/etc/profile - name: build shell: bash env: diff --git a/ci/lib.sh b/ci/lib.sh index 6c52154eac11e9..c6ccbf8c171dd7 100755 --- a/ci/lib.sh +++ b/ci/lib.sh @@ -391,9 +391,6 @@ linux-asan-ubsan) osx-meson) MESONFLAGS="$MESONFLAGS -Dcredential_helpers=osxkeychain" ;; -windows-*) - export NO_RUST=UnfortunatelyYes - ;; esac MAKEFLAGS="$MAKEFLAGS CC=${CC:-cc}" From 0e75d17ff78498645bf5d71df3a14a40d2fe1298 Mon Sep 17 00:00:00 2001 From: Kaartic Sivaraam Date: Tue, 15 Sep 2026 13:59:36 +0530 Subject: [PATCH 4/5] builtin/history: unuse the commit buffer after use Every call to repo_logmsg_reencode() must be paired with a call to repo_unuse_commit_buffer(), or we may leak an allocated buffer. We have such a leak in "git history", which we can fix by adding an unuse call. The leak-checking tests don't detect this because we only allocate a fresh buffer sometimes: when the message is reencoded, or when we had to load it fresh from the odb (e.g., because the commit was parsed from the commit graph rather than the object contents). But you can see it by running: make SANITIZE=leak cd t GIT_TEST_COMMIT_GRAPH=1 ./t3451-history-reword.sh Helped-by: Jeff King Signed-off-by: Kaartic Sivaraam Signed-off-by: Junio C Hamano --- builtin/history.c | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin/history.c b/builtin/history.c index 000155ad9c24d5..4f94221b11b21c 100644 --- a/builtin/history.c +++ b/builtin/history.c @@ -161,6 +161,7 @@ static int commit_tree_ext(struct repository *repo, free_commit_extra_headers(original_extra_headers); strbuf_release(&commit_message); free(original_author); + repo_unuse_commit_buffer(repo, commit_with_message, original_message); return ret; } From 12cb6293d6288865c1a133cf22accbaf99d13eb6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 16 Sep 2026 09:04:39 -0700 Subject: [PATCH 5/5] Git 2.56-rc1 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.56.0.adoc | 9 +++++++++ GIT-VERSION-GEN | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/RelNotes/2.56.0.adoc b/Documentation/RelNotes/2.56.0.adoc index 796a51e5a2998d..83d2f90daab35c 100644 --- a/Documentation/RelNotes/2.56.0.adoc +++ b/Documentation/RelNotes/2.56.0.adoc @@ -560,6 +560,11 @@ Performance, Internal Implementation, Development Support etc. backend-specific object source layers, making them pluggable for different object storage formats. + * When cross-compiling with Cargo, the output artifact is placed in a + target-specific subdirectory, which causes the build system to fail + to locate it. The build system has been updated to respect the + 'CARGO_BUILD_TARGET' environment variable. + Fixes since v2.55 ----------------- @@ -897,6 +902,10 @@ Fixes since v2.55 branch-switch message. (merge 2ba77ea828 hn/checkout-m-autostash-refine later to maint). + * The memory leak caused by not unusing the commit buffer returned by + repo_logmsg_reencode() during the rewording operation in 'git + history' has been plugged. + * Other code cleanup, docfix, build fix, etc. (merge 026636128f ss/submittingpatches-typofix later to maint). (merge d2af22cc21 jc/rerere-doc-typofix later to maint). diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 272bdc6e8c7682..e1ba5497648c07 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,6 +1,6 @@ #!/bin/sh -DEF_VER=v2.56.0-rc0 +DEF_VER=v2.56.0-rc1 LF=' '