====== Ubuntu - GIT - Undo changes ====== Generally there are three ways of reverting changes: * checkout * revert * reset ---- ===== Checkout ===== If you just need to revert specific files, you could run **git checkout** to retrieve an exact version. In the below example, I wanted to revert the “app.rb” file so that it only contains "Some app work". git log --oneline 1ab20e2 More experimentation 8d9b88d Experimenting with something cb1aa50 Do some good work d05eb2a Initial commit ls app.rb file1.rb README cat app.rb Some app work experimenting with something More experimentation git checkout cb1a app.rb cat app.rb Some app work git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) modified: app.rb git commit -am "Not a good experiment, moving back to good code" [master 5a39d14] Not a good experiment, moving back to good code 1 file changed, 2 deletions(-) git status On branch master nothing to commit, working directory clean git log --oneline 5a39d14 Not a good experiment, moving back to good code 1ab20e2 More experimentation 8d9b88d Experimenting with something cb1aa50 Do some good work d05eb2a Initial commit ---- ===== Revert ===== Revert will create a new commit undoing the changes made during a specific commit. It remove an entire commit in your project history. In this example, I'm going to undo the changes in last commit. As you could see, the history of the revert is kept. git log --oneline d69cd9c modify second line ab44e89 add second line 7a49968 first line cat hello.rb first line modify second line git revert d69c [master 6769261] Revert "modify second line" 1 file changed, 1 insertion(+), 1 deletion(-) git log --oneline 6769261 Revert "modify second line" d69cd9c modify second line ab44e89 add second line 7a49968 first line ---- ===== Reset ===== Unlike revert, reset will undo all subsequent commits. It has the potential to cause issues, so only use this to undo local changes. Most use reset to unstage files to match the most recent commit and perhaps create more focused commits/snapshots. The working directory is unchanged unless the **"–hard"** option is set. git log --oneline d69cd9c modify second line ab44e89 add second line 7a49968 first line git status On branch master nothing to commit, working directory clean git reset ab44 Unstaged changes after reset: M hello.rb git status On branch master Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changed in working directory) modified: hello.rb no changes added to commit (use "git add" and/or "git commit -a") git reset --hard ab44 HEAD is now at ab44e89 add second line git status On branch master nothing to commit, working directory clean git log --oneline ab44e89 add second line 7a49968 first line You could also reset to a tag. git tag v1.0 v1.1 git log --oneline 4f04459 add burrito 30ee499 add hamburger e521e3a Release v1.0 ab44e89 add second line 7a49968 first line git reset --hard v1.0 HEAD is now at e521e3a Release v1.0 git log --oneline e521e3a Release v1.0 ab44e89 add second line 7a49968 first line ls hello.rb git reset --hard v1.1 HEAD is now at 4f04459 add burrito git log --oneline 4f04459 add burrito 30ee499 add hamburger e521e3a Release v1.0 ab44e89 add second line 7a49968 first line ls burrito.rb hamburger.rb hello.rb