diff --git a/.gitignore b/.gitignore index 10c273c2bc..2093b0809b 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ edit-git-bash.exe /msi/obj/ /msi/package-versions.txt /msi/wix40-binaries.zip +/msix/root/ /nuget/GitForWindows.nuspec /nuget/Git-Windows-Minimal.nuspec /nuget/Git-Windows-Minimal.nuspec.unmoved diff --git a/msix/appxmanifest.xml.in b/msix/appxmanifest.xml.in new file mode 100644 index 0000000000..c86012ed28 --- /dev/null +++ b/msix/appxmanifest.xml.in @@ -0,0 +1,161 @@ + + + + + + + Git for Windows + The Git Development Community + Assets\StoreLogo.png + Git for Windows focuses on offering a lightweight, native set of tools that bring the full feature set of the Git to Windows while providing appropriate user interfaces for experienced users. + disabled + disabled + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msix/release.sh b/msix/release.sh new file mode 100644 index 0000000000..6f7cd257ee --- /dev/null +++ b/msix/release.sh @@ -0,0 +1,110 @@ +#!/bin/sh + +# Build the MSIX package for Git for Windows. + +. "$(dirname "$0")/../release-common.sh" + +case "$MSYSTEM" in +MINGW32) ARTIFACT_SUFFIX="x86";; +MINGW64) ARTIFACT_SUFFIX="x64";; +CLANGARM64) ARTIFACT_SUFFIX=arm64;; +esac + +# MSIX requires version in X.X.X.X format (numeric only) +# Convert Git for Windows versions like "2.47.1.windows.1" to "2.47.1.1" +# and test versions like "0-test" to "0.0.0.0" +MSIX_VERSION="$(echo "$VERSION" | sed -e 's/\.windows\./\./' -e 's/[^0-9.]//g')" +# Ensure we have exactly 4 numeric segments +while test "$(echo "$MSIX_VERSION" | tr -cd '.' | wc -c)" -lt 3 +do + MSIX_VERSION="$MSIX_VERSION.0" +done + +TARGET="$output_directory"/Git.GitforWindows_"$VERSION"_"$ARTIFACT_SUFFIX".msix + +# Generate MSIX asset images from SVG +ASSETS_DIR="$SCRIPT_PATH/Assets" +mkdir -p "$ASSETS_DIR" || +die "Could not create Assets directory" + +type rsvg-convert || +case "$ARCH" in +i686) pacman -Sy --noconfirm mingw-w64-i686-librsvg;; +x86_64) pacman -Sy --noconfirm mingw-w64-x86_64-librsvg;; +aarch64) pacman -Sy --noconfirm mingw-w64-clang-aarch64-librsvg;; +esac || +die "Could not install librsvg" + +SVG_SOURCE="$SCRIPT_PATH/../git-for-windows.svg" +for spec in \ + LockScreenLogo.png:24 \ + LockScreenLogo.scale-200.png:48 \ + Square150x150Logo.png:150 \ + Square150x150Logo.scale-200.png:300 \ + Square44x44Logo.png:44 \ + Square44x44Logo.scale-200.png:88 \ + Square44x44Logo.targetsize-24_altform-unplated.png:24 \ + StoreLogo.png:50 +do + name="${spec%%:*}" + size="${spec##*:}" + rsvg-convert -w "$size" -h "$size" "$SVG_SOURCE" \ + -o "$ASSETS_DIR/$name" || + die "Could not generate $name" +done + +prepare_root + +init_etc_gitconfig +generate_file_list "$@" +copy_dlls_to_libexec +unpack_pdbs + +# Find makeappx.exe from the Windows SDK +MAKEAPPX= +for sdk_dir in "/c/Program Files (x86)/Windows Kits/10/bin"/*/ +do + case "$ARCH" in + x86_64) sdk_arch=x64;; + i686) sdk_arch=x86;; + aarch64) sdk_arch=arm64;; + esac + if test -f "$sdk_dir$sdk_arch/makeappx.exe" + then + MAKEAPPX="$sdk_dir$sdk_arch/makeappx.exe" + fi +done +test -n "$MAKEAPPX" || +die "Could not find makeappx.exe in the Windows SDK" + +# Create MSIX + +MAPFILE=$SCRIPT_PATH/root/files.map +MANIFESTIN=$SCRIPT_PATH/appxmanifest.xml.in +MANIFESTOUT=$SCRIPT_PATH/root/appxmanifest.xml + +echo "Create MSIX" + +sed -e "s/@@VERSION@@/$MSIX_VERSION/g" <"$MANIFESTIN" >"$MANIFESTOUT" + +echo "[Files]" >"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/root/appxmanifest.xml\" \"AppxManifest.xml\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/root/bin/git.exe\" \"bin/git.exe\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/root/bin/sh.exe\" \"bin/sh.exe\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/root/bin/bash.exe\" \"bin/bash.exe\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/Assets/LockScreenLogo.png\" \"Assets/LockScreenLogo.png\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/Assets/LockScreenLogo.scale-200.png\" \"Assets/LockScreenLogo.scale-200.png\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/Assets/Square150x150Logo.png\" \"Assets/Square150x150Logo.png\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/Assets/Square150x150Logo.scale-200.png\" \"Assets/Square150x150Logo.scale-200.png\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/Assets/Square44x44Logo.png\" \"Assets/Square44x44Logo.png\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/Assets/Square44x44Logo.scale-200.png\" \"Assets/Square44x44Logo.scale-200.png\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/Assets/Square44x44Logo.targetsize-24_altform-unplated.png\" \"Assets/Square44x44Logo.targetsize-24_altform-unplated.png\"" >>"$MAPFILE" && +echo "\"$(cygpath -aw "$SCRIPT_PATH")/Assets/StoreLogo.png\" \"Assets/StoreLogo.png\"" >>"$MAPFILE" && +MSYS_ROOT="$(cygpath -aw /)" && +echo "$LIST" | while IFS= read -r entry; do + winpath="${entry//\//\\}" + echo "\"$MSYS_ROOT\\$winpath\" \"$winpath\"" +done >>"$MAPFILE" + +MSYS_NO_PATHCONV=1 "$MAKEAPPX" pack /v /o /f "$(cygpath -aw "$MAPFILE")" /p "$(cygpath -aw "$TARGET")" && +echo "Package created at $TARGET" \ No newline at end of file diff --git a/portable/release.sh b/portable/release.sh index 0b0248fa81..af91adcbe7 100755 --- a/portable/release.sh +++ b/portable/release.sh @@ -2,156 +2,27 @@ # Build the portable Git for Windows. -die () { - echo "$*" >&1 - exit 1 -} - -output_directory="$HOME" -include_pdbs= -while test $# -gt 0 -do - case "$1" in - --output) - shift - output_directory="$1" - ;; - --output=*) - output_directory="${1#*=}" - ;; - --include-pdbs) - include_pdbs=t - ;; - -*) - die "Unknown option: $1" - ;; - *) - break - esac - shift -done - -test $# -gt 0 || -die "Usage: $0 [--output=] [optional components]" - -test -d "$output_directory" || -die "Directory inaccessible: '$output_directory'" +. "$(dirname "$0")/../release-common.sh" case "$MSYSTEM" in -MINGW32) - BITNESS=32 - ARCH=i686 - ARTIFACT_SUFFIX="32-bit" - MD_ARG=128M - MINGW_PREFIX=mingw-w64-i686- - ;; -MINGW64) - BITNESS=64 - ARCH=x86_64 - ARTIFACT_SUFFIX="64-bit" - MD_ARG=256M - MINGW_PREFIX=mingw-w64-x86_64- - ;; -CLANGARM64) - BITNESS=64 - ARCH=aarch64 - ARTIFACT_SUFFIX=arm64 - MD_ARG=256M - MINGW_PREFIX=mingw-w64-clang-aarch64- - ;; -*) - die "Unhandled MSYSTEM: $MSYSTEM" - ;; +MINGW32) ARTIFACT_SUFFIX="32-bit";; +MINGW64) ARTIFACT_SUFFIX="64-bit";; +CLANGARM64) ARTIFACT_SUFFIX=arm64;; esac -MSYSTEM_LOWER=${MSYSTEM,,} -VERSION=$1 -shift + TARGET="$output_directory"/PortableGit-"$VERSION"-"$ARTIFACT_SUFFIX".7z.exe OPTS7="-m0=lzma -mqs -mlc=8 -mx=9 -md=$MD_ARG -mfb=273 -ms=256M " TMPPACK=/tmp.7z -SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd)" - -case "$SCRIPT_PATH" in -*" "*) - die "This script cannot handle spaces in $SCRIPT_PATH" - ;; -esac - - -# Generate a couple of files dynamically - -cp "$SCRIPT_PATH/../LICENSE.txt" "$SCRIPT_PATH/root/" || -die "Could not copy license file" - -mkdir -p "$SCRIPT_PATH/root/dev/mqueue" || -die "Could not make /dev/mqueue directory" - -mkdir -p "$SCRIPT_PATH/root/dev/shm" || -die "Could not make /dev/shm/ directory" -mkdir -p "$SCRIPT_PATH/root/etc" || -die "Could not make etc/ directory" - -mkdir -p "$SCRIPT_PATH/root/tmp" || -die "Could not make tmp/ directory" - -mkdir -p "$SCRIPT_PATH/root/bin" || -die "Could not make bin/ directory" - -cp /cmd/git.exe "$SCRIPT_PATH/root/bin/git.exe" && -cp /$MSYSTEM_LOWER/share/git/compat-bash.exe "$SCRIPT_PATH/root/bin/bash.exe" && -cp /$MSYSTEM_LOWER/share/git/compat-bash.exe "$SCRIPT_PATH/root/bin/sh.exe" || -die "Could not install bin/ redirectors" +prepare_root cp "$SCRIPT_PATH/../post-install.bat" "$SCRIPT_PATH/root/" || die "Could not copy post-install script" -etc_gitconfig="$(git -c core.editor=echo config --system -e 2>/dev/null)" && -etc_gitconfig="$(cygpath -au "$etc_gitconfig")" && -etc_gitconfig="${etc_gitconfig#/}" || -die "Could not determine the path of the system config" - -# Make a list of files to include -LIST="$(ARCH=$ARCH ETC_GITCONFIG="$etc_gitconfig" \ - PACKAGE_VERSIONS_FILE="$SCRIPT_PATH"/root/etc/package-versions.txt \ - sh "$SCRIPT_PATH"/../make-file-list.sh "$@" | - grep -v "^$etc_gitconfig$")" || -die "Could not generate file list" - -mkdir -p "$SCRIPT_PATH/root/${etc_gitconfig%/*}" && -cp /"$etc_gitconfig" "$SCRIPT_PATH/root/$etc_gitconfig" && -git config -f "$SCRIPT_PATH/root/$etc_gitconfig" \ - credential.helper manager || -die "Could not configure Git-Credential-Manager as default" -test 64 != $BITNESS || -git config -f "$SCRIPT_PATH/root/$etc_gitconfig" --unset pack.packSizeLimit -git config -f "$SCRIPT_PATH/root/$etc_gitconfig" core.fscache true - -case "$LIST" in -*/git-credential-helper-selector.exe*) - git config -f "$SCRIPT_PATH/root/$etc_gitconfig" \ - credential.helper helper-selector - ;; -esac - -git_core="$SCRIPT_PATH/root/$MSYSTEM_LOWER/libexec/git-core" && -rm -rf "$git_core" && -mkdir -p "$git_core" && -if test "$(stat -c %D /$MSYSTEM_LOWER/bin)" = "$(stat -c %D "$git_core")" -then - ln_or_cp=ln -else - ln_or_cp=cp -fi && -$ln_or_cp $(echo "$LIST" | sed -n "s|^$MSYSTEM_LOWER/bin/[^/]*\.dll$|/&|p") "$git_core" || -die "Could not copy .dll files into libexec/git-core/" - -test -z "$include_pdbs" || { - find "$SCRIPT_PATH/root" -name \*.pdb -exec rm {} \; && - "$SCRIPT_PATH"/../please.sh bundle-pdbs \ - --arch=$ARCH --unpack="$SCRIPT_PATH"/root -} || -die "Could not unpack .pdb files" +init_etc_gitconfig +generate_file_list "$@" +copy_dlls_to_libexec +unpack_pdbs TITLE="$BITNESS-bit" test $ARCH == "aarch64" && TITLE="ARM64" diff --git a/release-common.sh b/release-common.sh new file mode 100644 index 0000000000..75a5772601 --- /dev/null +++ b/release-common.sh @@ -0,0 +1,171 @@ +# Common helpers for release scripts. +# Source this file; it consumes the shared command-line flags and +# leaves the remaining positional parameters (optional components) in "$@". +# +# After sourcing, the following variables are set: +# output_directory, include_pdbs, VERSION, +# BITNESS, ARCH, MD_ARG, MINGW_PREFIX, MSYSTEM_LOWER, SCRIPT_PATH +# +# The following functions are available: +# die, prepare_root, init_etc_gitconfig, +# generate_file_list, copy_dlls_to_libexec, unpack_pdbs + +die () { + echo "$*" >&1 + exit 1 +} + +output_directory="$HOME" +include_pdbs= +while test $# -gt 0 +do + case "$1" in + --output) + shift + output_directory="$1" + ;; + --output=*) + output_directory="${1#*=}" + ;; + --include-pdbs) + include_pdbs=t + ;; + -*) + die "Unknown option: $1" + ;; + *) + break + esac + shift +done + +test $# -gt 0 || +die "Usage: $0 [--output=] [optional components]" + +test -d "$output_directory" || +die "Directory inaccessible: '$output_directory'" + +case "$MSYSTEM" in +MINGW32) + BITNESS=32 + ARCH=i686 + MD_ARG=128M + MINGW_PREFIX=mingw-w64-i686- + ;; +MINGW64) + BITNESS=64 + ARCH=x86_64 + MD_ARG=256M + MINGW_PREFIX=mingw-w64-x86_64- + ;; +CLANGARM64) + BITNESS=64 + ARCH=aarch64 + MD_ARG=256M + MINGW_PREFIX=mingw-w64-clang-aarch64- + ;; +*) + die "Unhandled MSYSTEM: $MSYSTEM" + ;; +esac +MSYSTEM_LOWER=${MSYSTEM,,} +VERSION=$1 +shift + +SCRIPT_PATH="$(cd "$(dirname "$0")" && pwd)" + +case "$SCRIPT_PATH" in +*" "*) + die "This script cannot handle spaces in $SCRIPT_PATH" + ;; +esac + +# Set up the root directory with common files and redirectors. +prepare_root () { + mkdir -p "$SCRIPT_PATH/root/" || + die "Could not make root" + + cp "$SCRIPT_PATH/../LICENSE.txt" "$SCRIPT_PATH/root/" || + die "Could not copy license file" + + mkdir -p "$SCRIPT_PATH/root/dev/mqueue" || + die "Could not make /dev/mqueue directory" + + mkdir -p "$SCRIPT_PATH/root/dev/shm" || + die "Could not make /dev/shm/ directory" + + mkdir -p "$SCRIPT_PATH/root/etc" || + die "Could not make etc/ directory" + + mkdir -p "$SCRIPT_PATH/root/tmp" || + die "Could not make tmp/ directory" + + mkdir -p "$SCRIPT_PATH/root/bin" || + die "Could not make bin/ directory" + + cp /cmd/git.exe "$SCRIPT_PATH/root/bin/git.exe" && + cp /$MSYSTEM_LOWER/share/git/compat-bash.exe "$SCRIPT_PATH/root/bin/bash.exe" && + cp /$MSYSTEM_LOWER/share/git/compat-bash.exe "$SCRIPT_PATH/root/bin/sh.exe" || + die "Could not install bin/ redirectors" +} + +# Detect the system gitconfig path. +# Sets: etc_gitconfig +init_etc_gitconfig () { + etc_gitconfig="$(git -c core.editor=echo config --system -e 2>/dev/null)" && + etc_gitconfig="$(cygpath -au "$etc_gitconfig")" && + etc_gitconfig="${etc_gitconfig#/}" || + die "Could not determine the path of the system config" +} + +# Generate the file list and configure the system gitconfig. +# Pass any optional components as arguments. +# Sets: LIST +generate_file_list () { + LIST="$(ARCH=$ARCH ETC_GITCONFIG="$etc_gitconfig" \ + PACKAGE_VERSIONS_FILE="$SCRIPT_PATH"/root/etc/package-versions.txt \ + sh "$SCRIPT_PATH"/../make-file-list.sh "$@" | + grep -v "^$etc_gitconfig$")" || + die "Could not generate file list" + + mkdir -p "$SCRIPT_PATH/root/${etc_gitconfig%/*}" && + cp /"$etc_gitconfig" "$SCRIPT_PATH/root/$etc_gitconfig" && + git config -f "$SCRIPT_PATH/root/$etc_gitconfig" \ + credential.helper manager || + die "Could not configure Git-Credential-Manager as default" + test 64 != $BITNESS || + git config -f "$SCRIPT_PATH/root/$etc_gitconfig" --unset pack.packSizeLimit + git config -f "$SCRIPT_PATH/root/$etc_gitconfig" core.fscache true + + case "$LIST" in + */git-credential-helper-selector.exe*) + git config -f "$SCRIPT_PATH/root/$etc_gitconfig" \ + credential.helper helper-selector + ;; + esac +} + +# Copy DLL files into libexec/git-core for runtime. +copy_dlls_to_libexec () { + git_core="$SCRIPT_PATH/root/$MSYSTEM_LOWER/libexec/git-core" && + rm -rf "$git_core" && + mkdir -p "$git_core" && + if test "$(stat -c %D /$MSYSTEM_LOWER/bin)" = "$(stat -c %D "$git_core")" + then + ln_or_cp=ln + else + ln_or_cp=cp + fi && + $ln_or_cp $(echo "$LIST" | sed -n "s|^$MSYSTEM_LOWER/bin/[^/]*\.dll$|/&|p") "$git_core" || + die "Could not copy .dll files into libexec/git-core/" +} + +# Unpack PDB files if --include-pdbs was given. +unpack_pdbs () { + test -z "$include_pdbs" || { + find "$SCRIPT_PATH/root" -name \*.pdb -exec rm {} \; && + "$SCRIPT_PATH"/../please.sh bundle-pdbs \ + --arch=$ARCH --unpack="$SCRIPT_PATH"/root + } || + die "Could not unpack .pdb files" +}