Last active
August 29, 2015 14:22
-
-
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
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
#!/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