Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Undo, Remove or Revert Specific Git Commits

undo-remove-or-revert-specific-git-commits.jpg

There's a couple of ways to do this depending on your use case.

Quick Jump:

We’re going to cover 3 use cases:

  • Undo last N commits
  • Remove a specific git commit
  • Revert a specific commit that was already pushed

The first 2 are meant to be done before you push anything where it’s safe to rewrite history without doing a force push while the last one is ok to do even if you pushed things.

If you want a local demo git repo to follow along, this will set one up:

mkdir -p /tmp/git-delete \
  && cd "${_}" \
  && rm -rf .git A B C \
  && git init \
  && touch A && git add A && git commit -m "Commit A" \
  && touch B && git add B && git commit -m "Commit B" \
  && touch C && git add C && git commit -m "Commit C"

# Undo Last N Commits

This will undo the last commit:

  • git reset HEAD~1
    • Optionally add --hard if you want the files in your working directory to be undone too, effectively wiping all traces of that commit’s contents

You can replace ~1 with the number of commits to go back. For example ~2 will undo the last 2 commits. That means both the 2nd to latest and latest commits will be undone.

You can always replace HEAD~N with the GIT_SHA^ too (the ^ is important). The operation acts the same. You can find the SHA with git log.

If you happen to want to undo all commits on a specific branch but don’t want to rm -rf .git the whole repo you can run git update-ref -d HEAD. Optionally run git reset --hard right after to remove the changes on disk.

# Remove Specific Commit

Let’s say you’ve made 3 local commits that you haven’t pushed yet and now you realize you want to delete only the middle (2nd) commit.

You can do an interactive rebase and drop the commit. I’ve written about using interactive rebase to change commits in the past, this will be similar.

  • git rebase --interactive HEAD~2
    • When prompted, replace “pick” with “drop” for the commit
    • It’ll perform the rebase for you automatically after you pick “drop”

Like the first example you can replace HEAD~N with the GIT_SHA^.

If you want to delete the oldest commit you can use --root instead of HEAD~N / GIT_SHA^.

By the way, before doing any of the above you’ll want to make sure you don’t already have something running like an active git commit prompt in your terminal or code editor. If you do it will fail and then you’ll need to git rebase --abort and try again. Don’t worry, it won’t break anything if this happens!

# Revert Pushed Commit

This last one is handy if you’ve commit and pushed something and now realize you want to reverse whatever you did. Maybe you found a bug a few days later.

  • git revert HEAD~2
    • Create your commit message as you see fit (it will be pre-populated)
    • Optionally add --no-commit to prevent it from auto-creating a commit so you can stage / review / etc. it

In the end this will add a new commit which is why it’s safe to do on pushed commits. It’s not rewriting history. You can check it out by running git show afterwards.

Like the other examples you can replace HEAD~N with the GIT_SHA but this time around you don’t want to put the ^, it will already target the SHA we want.

If you want to revert the oldest commit, you can use the GIT_SHA and it will work out of the box, but you wouldn’t be able to use HEAD~3 (the oldest commit in our old example).

The video below shows all of the above commands.

# Demo Video

Timestamps

  • 1:18 – Resetting the latest commit
  • 2:20 – Resetting the latest 2 commits
  • 2:50 – Reference by SHA instead of HEAD~N
  • 3:27 – Resetting the initial commit
  • 4:42 – Deleting 1 specific commit
  • 6:10 – Deleting the initial commit
  • 6:41 – What if the rebase fails?
  • 9:01 – Revert a commit
  • 10:12 – Referencing the SHA directly
  • 10:35 – Revert without auto-committing it

When was the last time you had to remove a git commit? Let me know below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per year (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments