Skip to content

Instantly share code, notes, and snippets.

@trevor-coleman
Created May 6, 2023 14:45
Show Gist options
  • Save trevor-coleman/116b90b43a4ba98085ee90a3e17ee715 to your computer and use it in GitHub Desktop.
Save trevor-coleman/116b90b43a4ba98085ee90a3e17ee715 to your computer and use it in GitHub Desktop.
Commit Reverser - Reverses Git Commits
#!/bin/bash
# to run: ./commit-reverser <first_commit>
# - creates a new branch, based on the parent of the provided commit, with the commits from HEAD
# to first-commit applied in reverse order
set -e
if [ -z "$1" ]; then
echo "Usage: $0 <first_commit>"
exit 1
fi
first_commit=$1
# Get the name of the original branch
original_branch_name=$(git rev-parse --abbrev-ref HEAD)
# Get the parent commit of the first commit
first_commit_parent=$(git rev-parse "${first_commit}^")
# Create a new branch based on the parent commit of the first commit
reverse_branch_name="${original_branch_name}-reversed"
git checkout -b "${reverse_branch_name}" "${first_commit_parent}"
# Perform a squash merge of the commits between the first commit and the tip of the original branch
git merge --squash "${original_branch_name}" --no-commit
# Commit the squash merge
last_commit=$(git rev-parse "${original_branch_name}")
merge_commit_message=$(git show -s --format=%s "${last_commit}")
git commit -m "${merge_commit_message} - reversed"
# Revert the commits in reverse order from the last commit to the first commit, excluding the first commit
for commit in $(git rev-list "${first_commit}..${original_branch_name}" | grep -v "${first_commit}"); do
git checkout "${reverse_branch_name}"
git revert --no-edit "${commit}"
done
echo "Created branch ${reverse_branch_name} with squash merge of ${original_branch_name} from ${first_commit} to ${last_commit} and reverted commits in reverse order from ${last_commit} to ${first_commit}, excluding the first commit."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment