#!/bin/bash # Initializes a git repository and pushes to a remote using credentials from arguments # # Usage: ./git-init-from-config.sh # # Arguments: # git-url - Repository URL (e.g., https://gitea.example.com/user/repo.git) # git-user - Git username # git-token - Git token or password # # The branch name will be read from the VERSION file (first line) set -e set -o pipefail if [ "$#" -lt 3 ]; then echo "Usage: $0 " echo "" echo "Arguments:" echo " git-url - Repository URL (e.g., https://gitea.example.com/user/repo.git)" echo " git-user - Git username" echo " git-token - Git token or password" exit 1 fi GIT_URL="$1" GIT_USER="$2" GIT_TOKEN="$3" if [ -z "$GIT_URL" ]; then echo "Error: git-url is required" exit 1 fi if [ -z "$GIT_USER" ]; then echo "Error: git-user is required" exit 1 fi if [ -z "$GIT_TOKEN" ]; then echo "Error: git-token is required" exit 1 fi if [ ! -f "VERSION" ]; then echo "Error: VERSION file not found in current directory" exit 1 fi GIT_BRANCH=$(head -n 1 VERSION | tr -d '[:space:]') if [ -z "$GIT_BRANCH" ]; then echo "Error: VERSION file is empty" exit 1 fi echo "Version detected: $GIT_BRANCH" if [[ "$GIT_URL" != http://* && "$GIT_URL" != https://* ]]; then echo "Error: URL must start with http:// or https://" exit 1 fi # 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) TOTAL_SIZE=$(du -sh . | cut -f1) echo "Added $TOTAL_FILES files (total size: $TOTAL_SIZE)" echo "Creating initial commit..." git commit -m "Initial commit" || echo "Nothing to commit or already committed" echo "Setting branch to $GIT_BRANCH..." git branch -M "$GIT_BRANCH" echo "Adding remote origin..." git remote remove origin 2>/dev/null || true git remote add origin "$GIT_URL" echo "Pushing to remote (this may take a while for large files)..." # 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"