Skip to content

Instantly share code, notes, and snippets.

@varunchandak
Last active December 1, 2025 16:04
Show Gist options
  • Select an option

  • Save varunchandak/0dc617b5ca87ea70564220fe01ff29d9 to your computer and use it in GitHub Desktop.

Select an option

Save varunchandak/0dc617b5ca87ea70564220fe01ff29d9 to your computer and use it in GitHub Desktop.
Re-sign Unverified Commits on current branch

Re sign PR Commits Script

This script automatically re signs all commits on the current branch using your configured GPG key. It is useful when a pull request contains unverified commits and you want to replace them with verified, GPG signed commits.

The script:

  1. Detects the merge base with the target branch (default: main).
  2. Creates a backup branch before rewriting anything.
  3. Re signs every commit after that merge base.
  4. Force pushes the rewritten history to update the pull request.

You only need to have your PR branch checked out and your GPG signing configured.


Requirements

  • GPG is installed and working.
  • Your GPG key is added to your GitHub account.
  • The email in your git config is a verified email on GitHub.
  • Your repository is clean (no uncommitted changes).

Check your settings:

git config user.email
git config user.signingkey
git config commit.gpgsign

Usage

Save the script as:

resign-pr-commits.sh

Then make it executable:

chmod +x resign-pr-commits.sh

Run it from inside your repository while checked out on the PR branch:

./resign-pr-commits.sh

Optional arguments

./resign-pr-commits.sh [base-branch] [remote]
  • base-branch defaults to main
  • remote defaults to origin

Examples:

./resign-pr-commits.sh
./resign-pr-commits.sh develop
./resign-pr-commits.sh main upstream

What the script does

  1. Ensures you are inside a git repository with a clean working tree.
  2. Detects the current branch.
  3. Fetches the latest base branch (default: main).
  4. Finds the merge base commit.
  5. Creates a backup branch such as:
backup/<your-branch>-before-resign-20250101T123456
  1. Runs:
git rebase --rebase-merges --exec 'git commit --amend --no-edit -S' <merge-base>

This replays each commit and re signs it.

  1. Force pushes the updated branch:
git push --force-with-lease

After the push, your PR will show fully verified commits.


Why you may still see unverified commits

Only commits on your PR branch are rewritten. The script cannot modify commits that are already part of the base branch (main, develop, etc.).

If you still see unverified commits:

1. They belong to the base branch

They cannot be rewritten. They will appear in the commit history view but they are not part of your PR changes.

2. The commits are signed locally but GitHub still shows Unverified

This happens if:

  • The email in the commit is not a verified email on GitHub.
  • The GPG key used is not uploaded to GitHub.

Check the signature locally:

git show --show-signature -1

If it shows Good signature, then you only need to fix email or GPG settings on GitHub.


Rollback

If anything goes wrong, restore your backup branch:

git checkout backup/<branch-name>

or reset your branch to that backup:

git checkout <original-branch>
git reset --hard backup/<branch-name>

Safe to use?

Yes. A backup branch is created every time, so your original commits are always recoverable.


#!/usr/bin/env sh
set -e
# Usage:
# ./resign-pr-commits.sh [base-branch] [remote]
#
# Defaults:
# base-branch = main
# remote = origin
BASE_BRANCH=${1:-main}
REMOTE=${2:-origin}
# Ensure we are in a git repo
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Error: not inside a git repository." >&2
exit 1
fi
# Ensure working tree is clean
if ! git diff-index --quiet HEAD --; then
echo "Error: working tree has uncommitted changes." >&2
echo "Commit or stash them before running this script." >&2
exit 1
fi
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "Current branch: $CURRENT_BRANCH"
echo "Base branch : $BASE_BRANCH"
echo "Remote : $REMOTE"
echo
# Fetch the latest base branch
echo "Fetching $REMOTE/$BASE_BRANCH..."
git fetch "$REMOTE" "$BASE_BRANCH"
# Find merge base between base branch and current branch
BASE_COMMIT=$(git merge-base "$REMOTE/$BASE_BRANCH" HEAD)
if [ -z "$BASE_COMMIT" ]; then
echo "Error: could not find merge base between HEAD and $REMOTE/$BASE_BRANCH." >&2
exit 1
fi
echo "Merge base commit: $BASE_COMMIT"
echo
# Create a backup branch before rewriting history
BACKUP_BRANCH="backup/${CURRENT_BRANCH}-before-resign-$(date +%Y%m%d%H%M%S)"
echo "Creating backup branch: $BACKUP_BRANCH"
git branch "$BACKUP_BRANCH"
echo
echo "Re signing all commits on $CURRENT_BRANCH after $BASE_COMMIT..."
echo "This will run:"
echo " git rebase --rebase-merges --exec 'git commit --amend --no-edit -S' $BASE_COMMIT"
echo
git rebase --rebase-merges --exec 'git commit --amend --no-edit -S' "$BASE_COMMIT"
echo
echo "Rebase and re signing completed."
echo "Pushing rewritten branch with --force-with-lease..."
echo
git push --force-with-lease "$REMOTE" "$CURRENT_BRANCH"
echo
echo "Done."
echo "If anything looks wrong, you can restore from backup branch:"
echo " git checkout $BACKUP_BRANCH"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment