Categories
git git-rebase git-reset

How do I delete a commit from a branch?

3927

How do I delete a commit from my branch history?
Should I use git reset --hard HEAD?

7

  • 56

    I think this is not a duplicate of Git undo last commit as it asks how to delete any commit from a branch. I also think non of the answers actually address this question. They all rewind the last commits, not cherry-pick and delete a single commit that may occurred a while ago.

    – Chris

    May 3, 2015 at 18:06

  • 18

    @Chris, the answer with git rebase -i HEAD~10 does address the question, as it does let you arbitrarily pick commits to delete. Git applies the commits in the range you specify one-by-one, ignoring commits you have removed from the log. I used this command today to get rid of the second and third most recent commits to my repo while keeping the top one. I agree that none of the other answers are satisfactory.

    – MST

    Jun 17, 2015 at 21:07

  • @MST yes, I should have said, non of the options in the accepted answer address this question, but you are absolutely right – that command seems to work

    – Chris

    Jul 10, 2015 at 12:43

  • 1

    I think git reset --soft HEAD~1 is exactly what you need. In such case you will undo commit and save your work. reset --hard will remove commit completely.

    – sergpank

    May 18, 2021 at 7:56


  • command: git log | head -n 1 | git revert

    Jun 1, 2021 at 8:03


5015

Careful: git reset --hard WILL DELETE YOUR WORKING DIRECTORY CHANGES. Be sure to stash any local changes you want to keep before running this command.

Assuming you are sitting on that commit, then this command will wack it…

git reset --hard HEAD~1

The HEAD~1 means the commit before head.

Or, you could look at the output of git log, find the commit id of the commit you want to back up to, and then do this:

git reset --hard <sha1-commit-id>

If you already pushed it, you will need to do a force push to get rid of it…

git push origin HEAD --force

However, if others may have pulled it, then you would be better off starting a new branch. Because when they pull, it will just merge it into their work, and you will get it pushed back up again.

If you already pushed, it may be better to use git revert, to create a “mirror image” commit that will undo the changes. However, both commits will be in the log.


FYI — git reset --hard HEAD is great if you want to get rid of WORK IN PROGRESS. It will reset you back to the most recent commit, and erase all the changes in your working tree and index.


Lastly, if you need to find a commit that you “deleted”, it is typically present in git reflog unless you have garbage collected your repository.

23

  • 69

    HEAD~1 or just HEAD^. If you pushed, you should use git revert instead.

    Aug 27, 2009 at 10:45

  • 16

    Obviously you can also use HEAD~n to “go back” n commits from your head. Maybe from this point you can interpreted ... --hard HEAD also as HEAD~0 => deleting work in progress.

    – nuala

    Jun 11, 2012 at 8:05


  • 14

    @beamrider9 imho git rebase is almost always the better way to delete commits (as described in Greg Hewgill’s answer) — not least because rebase does in fact include a big warning that you will be deleting stuff 4realz.

    Oct 26, 2012 at 6:39


  • 21

    this doesn’t delete changes from the commit tree though. The OP asked for an already made commit. If you reset --hard, and check the log --oneline --all, the commits still remain in the tree. How do we delete these commits from tree? Thanks.

    – Igbanam

    Mar 17, 2013 at 3:09

  • 24

    use reset --soft to delete local commit WITHOUT reverting work in progress!

    – user972946

    Sep 24, 2013 at 0:07

818

If you have not yet pushed the commit anywhere, you can use git rebase -i to remove that commit. First, find out how far back that commit is (approximately). Then do:

git rebase -i HEAD~N

The ~N means rebase the last N commits (N must be a number, for example HEAD~10). Then, you can edit the file that Git presents to you to delete the offending commit. On saving that file, Git will then rewrite all the following commits as if the one you deleted didn’t exist.

The Git Book has a good section on rebasing with pictures and examples.

Be careful with this though, because if you change something that you have pushed elsewhere, another approach will be needed unless you are planning to do a force push.

10

  • 2

    Note: If you happen to have any –no-ff merges in that last batch of commits, rebase will butcher them 🙁 This is mentioned under -p on this page. The problem is, if you replace -i with -p, you no longer get that pop up with the choices for “edit this commit, sqush that one”, etc etc. Anyone know the solution?

    – Bukov

    Apr 21, 2013 at 0:20

  • 4

    What if you have pushed it? (just me using the remote repo)

    Jan 7, 2015 at 6:02

  • 7

    @Costa you can use push -f to force the push and replace the remote branch with your local one. If it’s just your own remote repo, no problem. The trouble starts if somebody else has fetched in the meantime.

    Jan 7, 2015 at 6:16

  • 3

    I added and committed a data file that was too big for GitHub (yeah, it probably shouldn’t be in the source repo anyway; Oh well). When I tried to push, GitHub refused because of the too-large file. All I wanted to do was undo this one commit, while saving a few other unrelated commits that followed. The git rebase -i HEAD~5 command was exactly what I needed to completely remove this commit from my local repo! Thanks!

    – aldo

    Feb 24, 2015 at 18:07

  • 4

    @dumbledad: With rebase -i, the changes corresponding to the deleted commit are not preserved.

    May 10, 2016 at 17:43

639

Another possibility is one of my personal favorite commands:

git rebase -i <commit>~1

This will start the rebase in interactive mode -i at the point just before the commit you want to whack. The editor will start up listing all of the commits since then. Delete the line containing the commit you want to obliterate and save the file. Rebase will do the rest of the work, deleting only that commit, and replaying all of the others back into the log.

12

  • 4

    thx, btw if you run into any issues (like empty commits) you can use git rebase --continue

    – realgt

    Sep 28, 2012 at 15:43


  • 16

    Even easier: git rebase -i HEAD~1

    – mmell

    Sep 10, 2013 at 21:12


  • 3

    Wowzers. git rebase -i HEAD~1 really cleaned the repo up a lot! It’s hard to tell exactly what it did, but the whole thing looks a lot neater. A little alarming, actually.

    Dec 2, 2014 at 18:02

  • 8

    I think it’s worth noting that the commit is not obliterated, merely removed from the list. If you mess up, you can get the commit back using the reflog.

    – Zaz

    Apr 29, 2015 at 0:11

  • 9

    Is deleting the line the same as d/drop?

    – Leo

    May 25, 2016 at 18:37