Skip to content

Instantly share code, notes, and snippets.

@skyzyx
Created June 4, 2021 19:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skyzyx/d925dcfa879eab9c30ec594155e63cd1 to your computer and use it in GitHub Desktop.
Save skyzyx/d925dcfa879eab9c30ec594155e63cd1 to your computer and use it in GitHub Desktop.
Rollback a commit, and help others update their copies cleanly. Leverages skyzyx/git-commands

Removing a commit from a branch is similar to removing an item from a slice in Golang. You need to select the ranges you want to keep then append the latter to the former.


Go to the branch you want to work on.

git checkout {branch}

View the commits on the current branch. Identify the commit you want to remove.

git lolc

If it's the latest (or near-latest) commit, you can simply rollback and re-apply any later changes. Let's pretend it's the second-to-last commit, and the last commit we want to re-apply was a PR.

git rollback 2
git nuke # If you want to nuke the changes you rolled-back from the local branch.
git push --force {branch}

At this point, the remote HEAD and local HEAD have been rolled-back.

Now, does your PR branch contain the commit you just tried to remove?

git checkout {pr-branch}
git cherry-pit {commit}
git push --force {pr-branch}

Then select the "merge" button in the GitHub interface.

Already merged? Bummer. Do you still have the branch locally?

git checkout {merge-into-branch}
git merge --ff {pr-branch}
git push --force {merge-into-branch}

Now, anyone who has already pulled the bad commit into their repo will need to do a little work to clean-up. The commits on master/main are no longer fast-forward and that's gonna mess things up.

NOTE: If your "main" branch is main or master, go ahead and use the right name for the branch in the explanation below.

We're going to delete and re-fetch your local main branch.

Check out any other branch. It doesn't matter — you're just moving out of the way. (You can even create a new branch from the current one, just to get out of the way: git checkout -b new-branch.)

git checkout <any other branch>
git branch -D main

Fetch the available branches from the remote.

git fetch --all
git fetch {remote} --all

Create a new local branch from the upstream branch.

git checkout {remote}/main
git checkout -b main

And if you have a different upstream remote that you need to sync-up with, go ahead and force-push there as well.

git push -f origin master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment