59

Can you undo a past commit, that has long been merged into your git repository, via a git command? Or do you have to manually undo all the changes made in that commit?

edwardmlyte
  • 15,937
  • 23
  • 58
  • 83
  • 1
    Have a look on `git commit --amend` to modifiy the last commit or `git revert` where you can set the id of the commit you want to roll back. Youn can locate the commit's id with `git log` [Git Amend](http://git-scm.com/book/en/Git-Basics-Undoing-Things) [Git Revert](http://gitready.com/intermediate/2009/03/16/rolling-back-changes-with-revert.html) – dasheddot Oct 03 '12 at 08:28
  • Does this answer your question? [How do I undo the most recent local commits in Git?](https://stackoverflow.com/questions/927358/how-do-i-undo-the-most-recent-local-commits-in-git) – Damjan Pavlica Aug 16 '22 at 21:02
  • 1
    @DamianPavlica this question is specifically about an old commit which has had lots built on top of it. That answer you suggested is for the latest commit – edwardmlyte Aug 17 '22 at 23:25

2 Answers2

62

You can always just revert the changes from a single commit by doing:

git revert <commit-id>

note that this creates a new commit, undoing just those changes

E.g. git log --oneline

d806fc9 two
18cdfa2 bye
62c332e hello
c7811ee initial

Say I want to revert changes in commit 18cdfa2:

git revert 18cdfa2

We now have: git log -1 -p

commit fb9d6627a71636503fc9a1eb4f725937c783ecee
Author: Seth <sehe@mint12.(none)>
Date:   Wed Oct 3 10:32:46 2012 +0200

    Revert "bye"

    This reverts commit 18cdfa27c964b66b624be1030250757b745d6866.

diff --git a/a b/a
index 0907563..3b18e51 100644
--- a/a
+++ b/a
@@ -1 +1 @@
-bye world
+hello world
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Attention: This also undoes all changes done on the file system which have been there before the unwanted commit. – Franz Holzinger Jan 26 '23 at 09:18
  • @FranzHolzinger what do you mean? It doesn't in principle [live example](http://coliru.stacked-crooked.com/a/3a39a834f5564e5b). A conflicting worktree edit will prevent revert: [conflict error](http://coliru.stacked-crooked.com/a/18bb379efc57e526). Already committed conflicts will require manual conflict resolution as with any merge [like this](http://coliru.stacked-crooked.com/a/d6b5d4908ecb0f35). Perhaps depending on configuration it can *appear* to lose local changes - if you have advanced features like autostash, rerere enabled? – sehe Jan 26 '23 at 16:50
  • This is not about a conflict. But I have made local changes on the file. Then I did a wrong commit. But when undoing the last commit, also my changes on the files are reverted to the version from Git without any warning. – Franz Holzinger Jan 27 '23 at 13:19
  • @FranzHolzinger I showed you that's not what will happen. No doubt some other factor (a git reset or checkout maybe) was involved. – sehe Jan 27 '23 at 16:10
38

You can always do git revert <commit-hash> to undo a git commit. However, this in most cases is not helpful because it creates a new commit adding to your git reflog.

What I usually do when I have to step back is reset my branch to an earlier stage. To do this, do a git reflog and look for the HEAD position you want to move to.

rizwan@dragonstone:~/myrepo$ git reflog -3
8d386b8 HEAD@{0}: commit: I did something I don't want
2a59955 HEAD@{1}: commit: Feedback from PR #792
1023102 HEAD@{2}: checkout: moving from one branch to another

Now, say I want to move to commit hash 2a59955 and undo all the changes in 8d386b8. I would do:

Update: git reset --soft HEAD@{1} 

This will reset my branch to the initial state. Doing this will not only undo all the changes, but also stops tracking all the files that you might have added in this commit. By all means, this is the most efficient way to undo all the changes in a single commit.

This will undo all your changes. There is a hard reset meant to go back in time (at least from a git point of view). Use --hard in place of --soft for this

automaticAllDramatic
  • 2,025
  • 1
  • 21
  • 25
  • 1
    I would argue that it is helpful partly *due* to the fact that it creates a new commit. What if you want to undo your undoing? What if you want to be aware later that you've done reverting? also, one should mention committing+pushing, too, as just resetting doesn't change the commit history as such. – eis Oct 03 '12 at 09:30
  • Yes, it does not and I agree that it is important to have a history of reverted commits too. Resetting helps when you want to move a step back and start over from the last state. Also, resetting stays in your logs and it not like you completely erase the commit. – automaticAllDramatic Oct 03 '12 at 09:37
  • 8
    SOFT! You use SOFT! You LOSE your changes with that command. I was looking for how to undo a commit which committed too much (damn, intellij) so here's a warning for the next guy. – cmp Sep 15 '15 at 21:38
  • 2
    Does the answer need updating to SOFT? Also, refer to http://stackoverflow.com/a/21778/509213 to recover from an unwanted HARD reset. – edwardmlyte Sep 16 '15 at 10:00