#!/usr/bin/env bash set -Eeuo pipefail usage() { cat <<'USAGE' Usage: ./upload_to_github.sh [options] Options: -m, --message MESSAGE Commit message. Default: "Update AutoCalib-Workshop" -r, --repo-url URL GitHub repository URL. Uses existing origin if omitted. -b, --branch BRANCH Branch to push. Default: current branch. --remote NAME Git remote name. Default: origin. --dry-run Print commands without changing anything. -h, --help Show this help. Examples: ./upload_to_github.sh -m "Initial upload" ./upload_to_github.sh -r https://github.com/USER/REPO.git -m "Upload project" GITHUB_REPO_URL=git@github.com:USER/REPO.git ./upload_to_github.sh USAGE } die() { echo "Error: $*" >&2 exit 1 } run() { echo "+ $*" if [[ "${DRY_RUN}" != "1" ]]; then "$@" fi } PROJECT_DIR="${PROJECT_DIR:-$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)}" REMOTE_NAME="${REMOTE_NAME:-origin}" REPO_URL="${GITHUB_REPO_URL:-}" BRANCH="${BRANCH:-}" COMMIT_MESSAGE="${COMMIT_MESSAGE:-Update AutoCalib-Workshop}" DRY_RUN=0 while [[ $# -gt 0 ]]; do case "$1" in -m|--message) [[ $# -ge 2 ]] || die "missing value for $1" COMMIT_MESSAGE="$2" shift 2 ;; -r|--repo-url) [[ $# -ge 2 ]] || die "missing value for $1" REPO_URL="$2" shift 2 ;; -b|--branch) [[ $# -ge 2 ]] || die "missing value for $1" BRANCH="$2" shift 2 ;; --remote) [[ $# -ge 2 ]] || die "missing value for $1" REMOTE_NAME="$2" shift 2 ;; --dry-run) DRY_RUN=1 shift ;; -h|--help) usage exit 0 ;; *) die "unknown option: $1" ;; esac done command -v git >/dev/null 2>&1 || die "git is not installed" [[ -d "${PROJECT_DIR}" ]] || die "project directory does not exist: ${PROJECT_DIR}" cd "${PROJECT_DIR}" if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then run git init fi CURRENT_BRANCH="$(git branch --show-current 2>/dev/null || true)" if [[ -z "${BRANCH}" ]]; then if [[ -n "${CURRENT_BRANCH}" ]]; then BRANCH="${CURRENT_BRANCH}" elif git rev-parse --verify HEAD >/dev/null 2>&1; then die "detached HEAD; provide a branch with -b or BRANCH=..." else BRANCH="main" fi fi if [[ -n "${CURRENT_BRANCH}" && "${CURRENT_BRANCH}" != "${BRANCH}" ]]; then if git show-ref --verify --quiet "refs/heads/${BRANCH}"; then run git switch "${BRANCH}" else run git switch -c "${BRANCH}" fi fi if git remote get-url "${REMOTE_NAME}" >/dev/null 2>&1; then if [[ -n "${REPO_URL}" ]]; then run git remote set-url "${REMOTE_NAME}" "${REPO_URL}" fi else [[ -n "${REPO_URL}" ]] || die "remote '${REMOTE_NAME}' does not exist; provide --repo-url URL" run git remote add "${REMOTE_NAME}" "${REPO_URL}" fi HAS_WORKTREE_CHANGES=0 if ! git diff --quiet || ! git diff --cached --quiet || [[ -n "$(git ls-files --others --exclude-standard)" ]]; then HAS_WORKTREE_CHANGES=1 fi if [[ "${HAS_WORKTREE_CHANGES}" == "1" && "${DRY_RUN}" != "1" ]]; then [[ -n "$(git config --get user.name || true)" ]] || die "git user.name is not set" [[ -n "$(git config --get user.email || true)" ]] || die "git user.email is not set" fi run git add -A if git diff --cached --quiet; then echo "No staged changes to commit." else run git commit -m "${COMMIT_MESSAGE}" fi run git push -u "${REMOTE_NAME}" "${BRANCH}" echo "Done."