From b89f39cbac6abb23ce1f6a987dc864181af2f395 Mon Sep 17 00:00:00 2001
From: Dennis Ameling <dennis@dennisameling.com>
Date: Tue, 4 Oct 2022 09:58:10 +0200
Subject: [PATCH 1/6] bswap.h: add support for built-in bswap functions

Newer compiler versions, like GCC 10 and Clang 12, have built-in
functions for bswap32 and bswap64. This comes in handy, for example,
when targeting CLANGARM64 on Windows, which would not be supported
without this logic.

Signed-off-by: Dennis Ameling <dennis@dennisameling.com>
---
 compat/bswap.h | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/compat/bswap.h b/compat/bswap.h
index b34054f2bd7284..9e0f98e00b93a4 100644
--- a/compat/bswap.h
+++ b/compat/bswap.h
@@ -35,7 +35,19 @@ static inline uint64_t default_bswap64(uint64_t val)
 #undef bswap32
 #undef bswap64
 
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+/**
+ * __has_builtin is available since Clang 10 and GCC 10.
+ * Below is a fallback for older compilers.
+ */
+#ifndef __has_builtin
+	#define __has_builtin(x) 0
+#endif
+
+#if __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)
+#define bswap32(x) __builtin_bswap32((x))
+#define bswap64(x) __builtin_bswap64((x))
+
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
 
 #define bswap32 git_bswap32
 static inline uint32_t git_bswap32(uint32_t x)

From 2feeadb0d3fb7a631489e36d861d112d46423f2a Mon Sep 17 00:00:00 2001
From: Dennis Ameling <dennis@dennisameling.com>
Date: Tue, 4 Oct 2022 09:59:32 +0200
Subject: [PATCH 2/6] config.mak.uname: add support for clangarm64

CLANGARM64 is a relatively new MSYSTEM added by the MSYS2 team. In order
to have Git build correctly for this platform, let's add some
configuration for it to config.mak.uname.

Signed-off-by: Dennis Ameling <dennis@dennisameling.com>
---
 config.mak.uname | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/config.mak.uname b/config.mak.uname
index b12d4e168ae119..1e5d89f1aa4a73 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -724,6 +724,10 @@ ifeq ($(uname_S),MINGW)
 		prefix = /mingw64
 		HOST_CPU = x86_64
 		BASIC_LDFLAGS += -Wl,--pic-executable,-e,mainCRTStartup
+        else ifeq (CLANGARM64,$(MSYSTEM))
+		prefix = /clangarm64
+		HOST_CPU = aarch64
+		BASIC_LDFLAGS += -Wl,--pic-executable,-e,mainCRTStartup
         else
 		COMPAT_CFLAGS += -D_USE_32BIT_TIME_T
 		BASIC_LDFLAGS += -Wl,--large-address-aware

From 6c2e17eca68b143eff7b33d195bc66a486471547 Mon Sep 17 00:00:00 2001
From: Johannes Schindelin <johannes.schindelin@gmx.de>
Date: Sun, 20 Apr 2025 21:41:43 +0200
Subject: [PATCH 3/6] mingw: do not use nedmalloc on Windows/ARM64

It does not compile there, and seeing as nedmalloc has been pretty much
unmaintained since at least November 2017, as per
https://github.com/ned14/nedmalloc/issues/20#issuecomment-343432314,
there is also no hope that any fixes will materialize there.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 config.mak.uname | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/config.mak.uname b/config.mak.uname
index 1e5d89f1aa4a73..6222d2c5a48ca1 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -742,7 +742,9 @@ ifeq ($(uname_S),MINGW)
 	HAVE_LIBCHARSET_H = YesPlease
 	USE_GETTEXT_SCHEME = fallthrough
 	USE_LIBPCRE = YesPlease
-	USE_NED_ALLOCATOR = YesPlease
+	ifneq (CLANGARM64,$(MSYSTEM))
+		USE_NED_ALLOCATOR = YesPlease
+	endif
         ifeq (/mingw64,$(subst 32,64,$(prefix)))
 		# Move system config into top-level /etc/
 		ETC_GITCONFIG = ../etc/gitconfig

From c89ead8eaba7f824d6a4828964f8384f60b17101 Mon Sep 17 00:00:00 2001
From: Johannes Schindelin <johannes.schindelin@gmx.de>
Date: Tue, 25 Feb 2025 10:17:12 +0000
Subject: [PATCH 4/6] msvc: do handle builds on Windows/ARM64

Git for Windows/ARM64 settled on using `clang` to compile `git.exe`, and
hence needs to run in a system where `MSYSTEM` is set to `CLANGARM64`
and the prefix to use is `/clangarm64`.

We already did that in the `MINGW` arm, i.e. for regular Git for Windows
builds using MINGW GCC (or `clang`'s shim pretending to be GCC), now it
is time to do the same in the MS Visual C part.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 config.mak.uname | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/config.mak.uname b/config.mak.uname
index 6222d2c5a48ca1..bd94f4580885a5 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -432,7 +432,11 @@ ifeq ($(uname_S),Windows)
         ifeq (MINGW32,$(MSYSTEM))
 		prefix = /mingw32
         else
-		prefix = /mingw64
+		ifeq (CLANGARM64,$(MSYSTEM))
+			prefix = /clangarm64
+		else
+			prefix = /mingw64
+		endif
         endif
 	# Prepend MSVC 64-bit tool-chain to PATH.
 	#

From 939bcb0dc63f7f9dff71588182c7f384341f8432 Mon Sep 17 00:00:00 2001
From: Johannes Schindelin <johannes.schindelin@gmx.de>
Date: Tue, 25 Feb 2025 10:21:52 +0000
Subject: [PATCH 5/6] mingw(arm64): do move the `/etc/git*` location

In fb5e3378f8 (mingw: move Git for Windows' system config where users
expect it, 2021-06-22), I moved the location of Git for Windows' system
config and system Git attributes file to the top-level `/etc/` directory
(because it is a much more obvious location than, say, `/mingw64/etc/`).

The patch relied on a very specific scenario that the newly-supported
Windows/ARM64 builds of `git.exe` fails to fall into. So let's broaden
the condition a bit, so that Windows/ARM64 builds also use that location
(instead of the even more obscure `/clangarm64/etc/` directory).

This fixes https://github.com/git-for-windows/git/issues/5431.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 config.mak.uname | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/config.mak.uname b/config.mak.uname
index bd94f4580885a5..9a95ba8c9ab56e 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -489,7 +489,7 @@ ifeq ($(uname_S),Windows)
 	NO_POSIX_GOODIES = UnfortunatelyYes
 	NATIVE_CRLF = YesPlease
 	DEFAULT_HELP_FORMAT = html
-ifeq (/mingw64,$(subst 32,64,$(prefix)))
+ifeq (/mingw64,$(subst 32,64,$(subst clangarm,mingw,$(prefix))))
 	# Move system config into top-level /etc/
 	ETC_GITCONFIG = ../etc/gitconfig
 	ETC_GITATTRIBUTES = ../etc/gitattributes
@@ -749,7 +749,7 @@ ifeq ($(uname_S),MINGW)
 	ifneq (CLANGARM64,$(MSYSTEM))
 		USE_NED_ALLOCATOR = YesPlease
 	endif
-        ifeq (/mingw64,$(subst 32,64,$(prefix)))
+        ifeq (/mingw64,$(subst 32,64,$(subst clangarm,mingw,$(prefix))))
 		# Move system config into top-level /etc/
 		ETC_GITCONFIG = ../etc/gitconfig
 		ETC_GITATTRIBUTES = ../etc/gitattributes

From e0e78bd5131a9efa64697cd7c0bd30965d13b41c Mon Sep 17 00:00:00 2001
From: Johannes Schindelin <johannes.schindelin@gmx.de>
Date: Tue, 15 Apr 2025 19:55:12 +0200
Subject: [PATCH 6/6] max_tree_depth: lower it for clangarm64 on Windows

Just as in b64d78ad02ca (max_tree_depth: lower it for MSVC to avoid
stack overflows, 2023-11-01), I encountered the same problem with the
clang builds on Windows/ARM64.

The symptom is an exit code 127 when t6700 tries to verify that `git
archive big` fails.

This exit code is reserved on Unix/Linux to mean "command not found".
Unfortunately in this case, it is the fall-back chosen by
Cygwin's `pinfo::status_exit()` method when encountering
the NSTATUS `STATUS_STACK_OVERFLOW`, see
https://github.com/cygwin/cygwin/blob/cygwin-3.6.1/winsup/cygwin/pinfo.cc#L171

I verified manually that the stack overflow always happens somewhere
around tree depth 1403, therefore 1280 should be a safe bound in these
instances.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 environment.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/environment.c b/environment.c
index 9e4c7781be049a..d948bb3c7059cc 100644
--- a/environment.c
+++ b/environment.c
@@ -82,6 +82,16 @@ int max_allowed_tree_depth =
 	 * the stack overflow can occur.
 	 */
 	512;
+#elif defined(GIT_WINDOWS_NATIVE) && defined(__clang__) && defined(__aarch64__)
+	/*
+	 * Similar to Visual C, it seems that on Windows/ARM64 the clang-based
+	 * builds have a smaller stack space available. When running out of
+	 * that stack space, a `STATUS_STACK_OVERFLOW` is produced. When the
+	 * Git command was run from an MSYS2 Bash, this unfortunately results
+	 * in an exit code 127. Let's prevent that by lowering the maximal
+	 * tree depth; This value seems to be low enough.
+	 */
+	1280;
 #else
 	2048;
 #endif