Skip to content

Instantly share code, notes, and snippets.

@pfrenssen
Last active August 29, 2015 14:22
Show Gist options
  • Save pfrenssen/1010a92ffa3e2abfdaec to your computer and use it in GitHub Desktop.
Save pfrenssen/1010a92ffa3e2abfdaec to your computer and use it in GitHub Desktop.
Script to remove a range of commits from all branches in a given remote
#!/bin/bash
#
# Removes a range of commits in all remote branches.
#
# Disclaimer: this will remove data on your remote repository. Use at your own
# risk.
# The commit that precedes the oldest commit that needs to be removed.
PRECEDING_COMMIT=ab6ce03927e46ba4fc71a0ccb7ed5d9854242c64
# The youngest commit in the range of commits that need to be removed.
YOUNGEST_COMMIT=3edcbcf239330c41151cc0e4258263a496c49b4e
# The remote to clean.
REMOTE=origin
# Check if the oldest commit is an ancestor of the youngest commit.
if ! git merge-base --is-ancestor $PRECEDING_COMMIT $YOUNGEST_COMMIT ; then
echo "Error: $PRECEDING_COMMIT is not an ancestor of $YOUNGEST_COMMIT."
exit 1
fi
# Update the repository.
git fetch $REMOTE
# Loop over all the branches in the remote.
for BRANCH in `git ls-remote --heads $REMOTE | sed 's|^.*refs/heads/||'` ; do
REMOTE_BRANCH="remotes/$REMOTE/$BRANCH"
# Check if the branch contains the offending commits.
if git merge-base --is-ancestor $YOUNGEST_COMMIT $REMOTE_BRANCH ; then
echo -e "\n# Cleaning branch $BRANCH"
# Check out the branch.
echo "Checking out branch $REMOTE_BRANCH"
git checkout -q $REMOTE_BRANCH
# Clean the branch.
echo "Removing offending commits."
git rebase --onto $PRECEDING_COMMIT $YOUNGEST_COMMIT HEAD
# Show a diff with the remote so that the result can be assessed.
echo "Outputting diff with remote. Please check if the result is as expected."
git diff $REMOTE_BRANCH
# Ask for confirmation before overwriting the remote.
read -p "Are you sure you want to force push the branch '$BRANCH' to the remote '$REMOTE' (y/n)? " CONFIRM
echo $CONFIRM
if [ "$CONFIRM" == "y" ] ; then
echo "git push $REMOTE HEAD:$BRANCH --force"
fi
else
echo -e "\n# Skipping branch ${BRANCH}. Offending commits are not present."
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment