Last active
October 23, 2025 07:34
-
-
Save chris-piekarski/1b67d00259e53b7d478b931cc92f0017 to your computer and use it in GitHub Desktop.
Bash script to help sign PRs from GitHub copilot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Rebase and GPG/SSH sign the last N (or all unsigned) commits. | |
| # Non-interactive, skips empty commits, with CLI flags for help and verbosity. | |
| set -euo pipefail | |
| # --- Colors --- | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| CYAN='\033[0;36m' | |
| BOLD='\033[1m' | |
| RESET='\033[0m' | |
| # --- Defaults --- | |
| VERBOSE=false | |
| DRYRUN=false | |
| # --- Help message --- | |
| show_help() { | |
| cat <<EOF | |
| ${BOLD}Usage:${RESET} $(basename "$0") [N] [options] | |
| Re-sign the last N commits (or automatically detect unsigned commits). | |
| ${BOLD}Options:${RESET} | |
| -h, --help Show this help message and exit | |
| -v, --verbose Print every git command executed | |
| -n, --dry-run Show what would happen but do not modify anything | |
| ${BOLD}Examples:${RESET} | |
| $(basename "$0") # Auto-detect unsigned commits | |
| $(basename "$0") 5 # Re-sign last 5 commits | |
| $(basename "$0") -v # Verbose mode | |
| EOF | |
| } | |
| # --- Parse flags --- | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -h|--help) show_help; exit 0 ;; | |
| -v|--verbose) VERBOSE=true; shift ;; | |
| -n|--dry-run) DRYRUN=true; shift ;; | |
| [0-9]*) N="$1"; shift ;; | |
| *) echo -e "${RED}Unknown argument:${RESET} $1"; show_help; exit 1 ;; | |
| esac | |
| done | |
| # --- Git repo check --- | |
| if ! REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null); then | |
| echo -e "${RED}β Not inside a git repository.${RESET}" | |
| exit 1 | |
| fi | |
| cd "$REPO_PATH" | |
| # --- Determine commit range --- | |
| if [[ -z "${N:-}" ]]; then | |
| echo -e "${CYAN}π Searching for oldest unsigned commit...${RESET}" | |
| LAST_UNSIGNED_LINE=$(git log --pretty="%H %G?" | grep -E " N$" | tail -n1 || true) | |
| if [[ -z "$LAST_UNSIGNED_LINE" ]]; then | |
| echo -e "${GREEN}β All commits are signed β nothing to rebase.${RESET}" | |
| exit 0 | |
| fi | |
| LAST_UNSIGNED_HASH=$(echo "$LAST_UNSIGNED_LINE" | awk '{print $1}') | |
| TOTAL=$(git rev-list --count "${LAST_UNSIGNED_HASH}..HEAD") | |
| N=$((TOTAL + 1)) | |
| echo -e "${YELLOW}β οΈ Oldest unsigned commit detected:${RESET}" | |
| git log --pretty=format:"%h %G? %s" -1 "$LAST_UNSIGNED_HASH" | |
| echo -e "π Will rebase last ${BOLD}$N${RESET} commits." | |
| else | |
| echo -e "${CYAN}βΉοΈ Using manual commit count: ${BOLD}$N${RESET}" | |
| fi | |
| # --- Verbose mode --- | |
| if $VERBOSE; then | |
| set -x | |
| fi | |
| # --- Dry-run mode --- | |
| if $DRYRUN; then | |
| echo -e "${YELLOW}[DRY RUN]${RESET} Would execute:" | |
| echo "git rebase HEAD~$N --exec 'git commit --amend --no-edit -S --allow-empty'" | |
| exit 0 | |
| fi | |
| # --- Safety tag --- | |
| RESTORE_TAG="pre-rebase-$(date +%Y%m%d-%H%M%S)" | |
| git tag "$RESTORE_TAG" || true | |
| echo -e "${CYAN}πΎ Created restore tag:${RESET} ${BOLD}$RESTORE_TAG${RESET}" | |
| # --- Show commits to be re-signed --- | |
| echo -e "${CYAN}π Commits to be re-signed:${RESET}" | |
| git log --pretty=format:"%h %G? %s" -$N || true | |
| echo | |
| read -p "$(echo -e ${YELLOW}"Proceed to re-sign last $N commits? (y/N) "${RESET})" confirm | |
| if [[ ! "$confirm" =~ ^[Yy]$ ]]; then | |
| echo -e "${RED}β Cancelled.${RESET}" | |
| exit 0 | |
| fi | |
| # --- Rebase operation --- | |
| echo -e "${CYAN}π Rebasing and signing commits non-interactively...${RESET}" | |
| git rebase HEAD~$N --exec 'git commit --amend --no-edit -S --allow-empty' || { | |
| echo -e "${RED}β Rebase failed.${RESET}" | |
| echo "To roll back: git rebase --abort || git reset --hard $RESTORE_TAG" | |
| exit 1 | |
| } | |
| # --- Verify --- | |
| echo -e "${GREEN}β Rebase complete. Verifying signatures:${RESET}" | |
| git log --pretty=format:"%h %G? %s" -$N | |
| echo | |
| read -p "$(echo -e ${YELLOW}"Push changes with --force-with-lease? (y/N) "${RESET})" pushconfirm | |
| if [[ "$pushconfirm" =~ ^[Yy]$ ]]; then | |
| git push --force-with-lease | |
| echo -e "${GREEN}π Push complete.${RESET}" | |
| else | |
| echo -e "${YELLOW}π Push skipped.${RESET}" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment