diff --git a/git-init-from-config.sh b/git-init-from-config.sh index a0ec66e..3ea6adb 100755 --- a/git-init-from-config.sh +++ b/git-init-from-config.sh @@ -12,6 +12,7 @@ # The branch name will be read from the VERSION file (first line) set -e +set -o pipefail if [ "$#" -lt 3 ]; then echo "Usage: $0 " @@ -56,29 +57,43 @@ fi echo "Version detected: $GIT_BRANCH" -if [[ "$GIT_URL" == https://* ]]; then - URL_WITHOUT_PROTOCOL="${GIT_URL#https://}" - AUTH_URL="https://${GIT_USER}:${GIT_TOKEN}@${URL_WITHOUT_PROTOCOL}" -elif [[ "$GIT_URL" == http://* ]]; then - URL_WITHOUT_PROTOCOL="${GIT_URL#http://}" - AUTH_URL="http://${GIT_USER}:${GIT_TOKEN}@${URL_WITHOUT_PROTOCOL}" -else +if [[ "$GIT_URL" != http://* && "$GIT_URL" != https://* ]]; then echo "Error: URL must start with http:// or https://" exit 1 fi -echo "Configuring Git for large files..." -# Increase HTTP post buffer to handle large files (500MB) -git config --global http.postBuffer 524288000 -# Optimize compression for large files -git config --global core.compression 9 -# Increase timeout for long operations (30 minutes) -git config --global http.lowSpeedLimit 0 -git config --global http.lowSpeedTime 1800 +# Credentials are passed to git through GIT_ASKPASS instead of being embedded in +# the remote URL. Embedding breaks on passwords containing '@', '#', ':' or '/' +# (git splits the userinfo on the first '@'), and it would also persist the +# secret in .git/config and echo it back in error messages. +ASKPASS_SCRIPT=$(mktemp "${TMPDIR:-/tmp}/git-askpass.XXXXXX") +trap 'rm -f "$ASKPASS_SCRIPT"' EXIT +cat > "$ASKPASS_SCRIPT" <<'ASKPASS' +#!/bin/bash +case "$1" in + *[Uu]sername*) printf '%s' "$GIT_ASKPASS_USER" ;; + *) printf '%s' "$GIT_ASKPASS_TOKEN" ;; +esac +ASKPASS +chmod 700 "$ASKPASS_SCRIPT" +export GIT_ASKPASS="$ASKPASS_SCRIPT" +export GIT_ASKPASS_USER="$GIT_USER" +export GIT_ASKPASS_TOKEN="$GIT_TOKEN" +export GIT_TERMINAL_PROMPT=0 echo "Initializing git repository..." git init +echo "Configuring Git for large files..." +# Repository-local so the caller's global git config is left untouched. +# Increase HTTP post buffer to handle large files (500MB) +git config http.postBuffer 524288000 +# Optimize compression for large files +git config core.compression 9 +# Increase timeout for long operations (30 minutes) +git config http.lowSpeedLimit 0 +git config http.lowSpeedTime 1800 + echo "Adding all files (this may take a while for large files)..." git add -A TOTAL_FILES=$(git ls-files | wc -l) @@ -93,17 +108,12 @@ git branch -M "$GIT_BRANCH" echo "Adding remote origin..." git remote remove origin 2>/dev/null || true -git remote add origin "$AUTH_URL" +git remote add origin "$GIT_URL" echo "Pushing to remote (this may take a while for large files)..." -# Use progress flag to show upload progress -git push --progress -u origin "$GIT_BRANCH" 2>&1 | while IFS= read -r line; do - echo "$line" - # Show progress indicators - if [[ "$line" =~ (Counting|Compressing|Writing|remote:) ]]; then - echo "$line" - fi -done +# Not piped: piping made the exit status that of the pipe's last command, so a +# failed push was reported as success. +git push --progress -u origin "$GIT_BRANCH" echo "" echo "Done! Repository pushed to $GIT_URL on branch $GIT_BRANCH"