#!/usr/bin/env bash # Upload this workspace to a Git remote. # # Usage: # ./upload_git.sh -r [-b branch] [-m "commit message"] # ./upload_git.sh --remote --branch main --message "Update README" # # Notes: # - If origin already exists, -r/--remote can be omitted. # - If the working tree has changes, provide -m/--message to commit them. # - This repository currently does not require Git LFS on the remote. set -euo pipefail REMOTE_NAME="${REMOTE_NAME:-origin}" REMOTE_URL="http://git.fairylandtech.com/whut/FaRui_Campus_ADS.git" BRANCH="origin/main" COMMIT_MESSAGE="Update project" NO_COMMIT="false" SET_REMOTE="false" usage() { sed -n '1,12p' "$0" cat <<'EOF' Options: -r, --remote Remote repository URL. Required if origin is absent. -b, --branch Branch to push. Defaults to current branch, then main. -m, --message Commit message for pending local changes. --no-commit Refuse to commit local changes; push only if clean. --set-remote Replace existing origin URL with --remote. -h, --help Show this help. Examples: ./upload_git.sh -r git@github.com:org/farui-campus-ads.git ./upload_git.sh -r git@github.com:org/farui-campus-ads.git -m "Update project README" ./upload_git.sh --remote https://github.com/org/farui-campus-ads.git --branch main EOF } log() { printf '[INFO] %s\n' "$*" } warn() { printf '[WARN] %s\n' "$*" >&2 } die() { printf '[ERROR] %s\n' "$*" >&2 exit 1 } while [[ $# -gt 0 ]]; do case "$1" in -r|--remote) [[ $# -ge 2 ]] || die "Missing value for $1" REMOTE_URL="$2" shift 2 ;; -b|--branch) [[ $# -ge 2 ]] || die "Missing value for $1" BRANCH="$2" shift 2 ;; -m|--message) [[ $# -ge 2 ]] || die "Missing value for $1" COMMIT_MESSAGE="$2" shift 2 ;; --no-commit) NO_COMMIT="true" shift ;; --set-remote) SET_REMOTE="true" shift ;; -h|--help) usage exit 0 ;; *) die "Unknown argument: $1" ;; esac done command -v git >/dev/null 2>&1 || die "git is not installed." REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || die "Not inside a Git repository." cd "$REPO_ROOT" LFS_COUNT="0" if git lfs version >/dev/null 2>&1; then git lfs install --local >/dev/null LFS_COUNT="$(git lfs ls-files | wc -l | tr -d ' ')" else warn "Git LFS is not installed. This is acceptable only when no LFS files are tracked." fi if [[ -z "$BRANCH" ]]; then BRANCH="$(git branch --show-current)" fi if [[ -z "$BRANCH" ]]; then BRANCH="main" fi if ! git show-ref --verify --quiet "refs/heads/$BRANCH"; then current_branch="$(git branch --show-current)" if [[ -n "$current_branch" ]]; then log "Renaming current branch '$current_branch' to '$BRANCH'." git branch -M "$BRANCH" else die "Branch '$BRANCH' does not exist and no current branch is active." fi fi if git remote get-url "$REMOTE_NAME" >/dev/null 2>&1; then existing_remote="$(git remote get-url "$REMOTE_NAME")" if [[ -n "$REMOTE_URL" && "$REMOTE_URL" != "$existing_remote" ]]; then if [[ "$SET_REMOTE" == "true" ]]; then log "Updating $REMOTE_NAME remote URL." git remote set-url "$REMOTE_NAME" "$REMOTE_URL" else die "$REMOTE_NAME already points to '$existing_remote'. Use --set-remote to replace it." fi fi else [[ -n "$REMOTE_URL" ]] || die "Remote '$REMOTE_NAME' is absent. Provide -r ." log "Adding $REMOTE_NAME remote: $REMOTE_URL" git remote add "$REMOTE_NAME" "$REMOTE_URL" fi status_output="$(git status --short)" if [[ -n "$status_output" ]]; then warn "Working tree has local changes:" printf '%s\n' "$status_output" >&2 if [[ "$NO_COMMIT" == "true" ]]; then die "Working tree is dirty and --no-commit was set." fi [[ -n "$COMMIT_MESSAGE" ]] || die "Provide -m \"commit message\" to commit pending changes before upload." log "Staging local changes." git add -A log "Creating commit: $COMMIT_MESSAGE" git commit -m "$COMMIT_MESSAGE" else log "Working tree is clean." fi log "LFS files tracked: $LFS_COUNT" log "Pushing branch '$BRANCH' to '$REMOTE_NAME'." git push -u "$REMOTE_NAME" "$BRANCH" log "Upload finished."