Require native Git runtime and bundle full manpages

- Remove the app fallback path when native Git is unavailable and show a startup blocker instead
- Fix native level setup for staged file counting and cherry-pick parity
- Improve manpage loading/search and bundle full Git documentation assets
- Integrate Git cross-compilation into AndroidProjectTooling.sh and remove debug AAB support
This commit is contained in:
Joe Tretter
2026-05-08 17:43:46 -05:00
parent 64743ff4a9
commit 4fab442939
219 changed files with 58133 additions and 129 deletions

View File

@@ -16,6 +16,11 @@ CMDLINE_TOOLS_LATEST_DIR="$CMDLINE_TOOLS_DIR/latest"
WRAPPER_JAR_PATH="$PROJECT_DIR/gradle/wrapper/gradle-wrapper.jar"
LOCAL_PROPERTIES_PATH="$PROJECT_DIR/local.properties"
HOST_GIT_BINARY="$PROJECT_DIR/build/host-git/libgit.so"
GIT_SRC_DIR="$TMP_DIR/git-src"
HOST_GIT_DIR="$PROJECT_DIR/build/host-git"
ANDROID_JNI_DIR="$PROJECT_DIR/app/src/main/jniLibs"
ANDROID_ASSET_MANPAGE_DIR="$PROJECT_DIR/app/src/main/assets/manpages"
ANDROID_API=24
ANDROID_CMDLINE_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"
GRADLE_DIST_URL="https://services.gradle.org/distributions/gradle-8.7-bin.zip"
@@ -24,6 +29,7 @@ ANDROID_NDK_PACKAGE="ndk;27.2.12479018"
ANDROID_CMAKE_PACKAGE="cmake;3.22.1"
ANDROID_NDK_DIR="$SDK_DIR/ndk/27.2.12479018"
ANDROID_CMAKE_DIR="$SDK_DIR/cmake/3.22.1"
ANDROID_TOOLBIN="$ANDROID_NDK_DIR/toolchains/llvm/prebuilt/linux-x86_64/bin"
STATE_TTL_SECONDS=86400
log() {
@@ -252,6 +258,128 @@ setup_env() {
export GRADLE_USER_HOME="$GRADLE_USER_HOME_DIR"
}
require_path() {
if [ ! -e "$1" ]; then
echo "Required path not found: $1" >&2
exit 1
fi
}
ensure_git_source() {
mkdir -p "$TMP_DIR"
if [ ! -d "$GIT_SRC_DIR/.git" ]; then
log "Cloning Git source"
git clone --depth 1 https://github.com/git/git.git "$GIT_SRC_DIR"
else
log "Using existing Git source checkout"
fi
}
common_git_make_args() {
printf '%s\n' \
NO_OPENSSL=YesPlease \
NO_CURL=YesPlease \
NO_EXPAT=YesPlease \
NO_GETTEXT=YesPlease \
NO_TCLTK=YesPlease \
NO_PERL=YesPlease \
NO_PYTHON=YesPlease \
NO_INSTALL_HARDLINKS=YesPlease \
NO_ICONV=YesPlease \
NO_REGEX=NeedsStartEnd \
HAVE_ALLOCA_H=YesPlease \
HAVE_PATHS_H=YesPlease \
HAVE_CLOCK_GETTIME=YesPlease \
HAVE_CLOCK_MONOTONIC=YesPlease \
HAVE_GETDELIM=YesPlease \
FREAD_READS_DIRECTORIES=UnfortunatelyYes \
CSPRNG_METHOD=
}
bundle_git_manpages() {
require_path "$GIT_SRC_DIR/Documentation"
log "Bundling full Git manpage sources"
mkdir -p "$ANDROID_ASSET_MANPAGE_DIR"
find "$ANDROID_ASSET_MANPAGE_DIR" -type f -name '*.txt' -delete
while IFS= read -r manpage_source; do
local manpage_name
manpage_name="$(basename "$manpage_source")"
cp "$manpage_source" "$ANDROID_ASSET_MANPAGE_DIR/${manpage_name%.*}.txt"
done < <(find "$GIT_SRC_DIR/Documentation" -maxdepth 1 -type f \( -name 'git*.txt' -o -name 'git*.adoc' -o -name 'gitignore.txt' -o -name 'gitignore.adoc' \))
}
build_host_git() {
ensure_git_source
bundle_git_manpages
log "Building Git for development host"
cd "$GIT_SRC_DIR"
make clean >/dev/null 2>&1 || true
mapfile -t make_args < <(common_git_make_args)
make -j"$(nproc 2>/dev/null || printf 4)" "${make_args[@]}" git
mkdir -p "$HOST_GIT_DIR"
cp git "$HOST_GIT_BINARY"
chmod 755 "$HOST_GIT_BINARY"
log "Host test Git binary: $HOST_GIT_BINARY"
"$HOST_GIT_BINARY" --version
cd "$PROJECT_DIR"
}
build_android_git_for_abi() {
local abi="$1"
local cc="$2"
local output_dir="$ANDROID_JNI_DIR/$abi"
require_path "$ANDROID_TOOLBIN/$cc"
log "Building Git for Android $abi"
cd "$GIT_SRC_DIR"
make clean >/dev/null 2>&1 || true
mapfile -t make_args < <(common_git_make_args)
make -j"$(nproc 2>/dev/null || printf 4)" \
uname_S=Android \
uname_O=Android \
NO_PTHREADS=YesPlease \
NO_LIBGEN_H=YesPlease \
HAVE_DEV_TTY=YesPlease \
CC="$cc" \
AR=llvm-ar \
RANLIB=llvm-ranlib \
STRIP=llvm-strip \
"${make_args[@]}" \
git
log "Validating Android $abi binary"
file git
readelf -h git | sed -n '1,12p'
mkdir -p "$output_dir"
llvm-strip -s git -o "$output_dir/libgit.so"
chmod 755 "$output_dir/libgit.so"
ls -lh "$output_dir/libgit.so"
cd "$PROJECT_DIR"
}
build_android_git() {
ensure_git_source
bundle_git_manpages
require_path "$ANDROID_NDK_DIR"
export PATH="$ANDROID_TOOLBIN:$PATH"
build_android_git_for_abi "arm64-v8a" "aarch64-linux-android${ANDROID_API}-clang"
build_android_git_for_abi "armeabi-v7a" "armv7a-linux-androideabi${ANDROID_API}-clang"
build_android_git_for_abi "x86" "i686-linux-android${ANDROID_API}-clang"
build_android_git_for_abi "x86_64" "x86_64-linux-android${ANDROID_API}-clang"
}
build_all_git_targets() {
build_host_git
build_android_git
}
ensure_sdk_packages() {
setup_env
@@ -302,6 +430,7 @@ maybe_run_operation() {
local should_bump_version="false"
local should_auto_commit="false"
local should_compile_host_git="false"
local should_bundle_manpages="false"
case "$mode" in
--build)
@@ -311,14 +440,7 @@ maybe_run_operation() {
artifact_target="$PROJECT_DIR/app/build/outputs/apk/debug/githug-android-debug.apk"
should_bump_version="true"
should_auto_commit="true"
;;
--build-aab)
gradle_task="bundleDebug"
artifact_label="debug AAB"
artifact_source="$PROJECT_DIR/app/build/outputs/bundle/debug/app-debug.aab"
artifact_target="$PROJECT_DIR/app/build/outputs/bundle/debug/githug-android-debug.aab"
should_bump_version="true"
should_auto_commit="true"
should_bundle_manpages="true"
;;
--build-release-aab)
gradle_task="bundleRelease"
@@ -327,6 +449,7 @@ maybe_run_operation() {
artifact_target="$PROJECT_DIR/app/build/outputs/bundle/release/githug-android-release.aab"
should_bump_version="true"
should_auto_commit="true"
should_bundle_manpages="true"
;;
--test)
gradle_task="testDebugUnitTest"
@@ -334,7 +457,7 @@ maybe_run_operation() {
should_compile_host_git="true"
;;
--compile-git)
"$PROJECT_DIR/CompileGitForAllTargetPlatforms.sh" --all
build_all_git_targets
return
;;
*)
@@ -347,9 +470,13 @@ maybe_run_operation() {
bump_android_version
fi
if [ "$should_compile_host_git" = "true" ]; then
"$PROJECT_DIR/CompileGitForAllTargetPlatforms.sh" --host
build_host_git
export GITHUG_TEST_GIT_BINARY="$HOST_GIT_BINARY"
fi
if [ "$should_bundle_manpages" = "true" ]; then
ensure_git_source
bundle_git_manpages
fi
log "Running $artifact_label with --no-daemon"
"$PROJECT_DIR/gradlew" --no-daemon "$gradle_task"
@@ -371,10 +498,9 @@ maybe_run_operation() {
print_usage() {
cat <<EOF_USAGE
Usage: bash ./AndroidProjectTooling.sh [--build | --build-aab | --build-release-aab | --test | --compile-git]
Usage: bash ./AndroidProjectTooling.sh [--build | --build-release-aab | --test | --compile-git]
--build Set up the environment and build the debug APK
--build-aab Set up the environment and build the debug Android App Bundle (AAB)
--build-release-aab Set up the environment and build a release Android App Bundle (AAB)
--test Set up the environment, compile host Git, and run the debug JVM unit tests with it
--compile-git Compile Git for the development host and all Android target ABIs
@@ -383,7 +509,7 @@ EOF_USAGE
validate_args() {
case "${1:-}" in
""|--build|--build-aab|--build-release-aab|--test|--compile-git)
""|--build|--build-release-aab|--test|--compile-git)
;;
*)
echo "Unknown argument: $1" >&2
@@ -405,6 +531,7 @@ main() {
require_tool clang
require_tool pkg-config
require_tool readelf
require_tool file
ensure_dir "$TMP_DIR"
ensure_dir "$SDK_DIR"
@@ -426,7 +553,6 @@ main() {
log "To compile Git for host and Android ABIs: bash ./AndroidProjectTooling.sh --compile-git"
log "To build without a background Gradle daemon: ./gradlew --no-daemon assembleDebug"
log "To set up and build in one step: bash ./AndroidProjectTooling.sh --build"
log "To set up and build a debug AAB in one step: bash ./AndroidProjectTooling.sh --build-aab"
log "To set up and build a release AAB in one step: bash ./AndroidProjectTooling.sh --build-release-aab"
log "To set up and run unit tests with compiled host Git: bash ./AndroidProjectTooling.sh --test"
}