Master Git (part II). Viewing and undoing commits.
We continue to talk about git and in this post we’ll talk about a few more things that make people confused - viewing old versions of your files and undoing commits.
How to view the old version of my repository?
To view a previous version of your repository, you can use the following command:
$ git checkout <commit> # you need to provide a commit hash or tag
Checking out an old commit is a read-only operation. So you it won’t affect the current state of your repository. Although you can create a separate branch to make your changes on the previous commit permanent.
After you’re finished viewing the old version of your repository, you can move the HEAD back to the tip of your branch and load the current state of your repository:
git checkout <current_branch_name>
How to revert back to an old version of a file?
git checkout <commit> <file>
This turns the
<file> that resides in the working directory into an exact copy of the one from
<commit> and adds it to the staging area. You can then re-commit the old version as you would any other file. This basically serves as a way to revert back to an old version of an individual file.
How to undo a commit?
There are tree commands that you can use.
In cases when you forgot to include files in the previous commit or wish to rewrite its message,
git commit --amend is the command to use. This command lets you combine files in your index with the previous commit.
Let’s imagine that we made a commit but forgot to include a certain file.
To edit the commit and add the forgotten file to it without changing the message (
--no-edit), we first stage the file and then run
git commit --amend command:
Most of the times, I use
git commit --amend command to simply change the message of the previous commit.
Important thing you should know before using this command is that
amending removes the previous commit and replaces it with a new commit. So you should never use amend commits that have been pushed to a public repository. Otherwise, to other team members who have based their work on amended commit, it will look like the bases of their work disappeared from the project history.
Another command to undo a commit is git revert
$ git revert <commit>
git revert command undoes the changes introduced by the commit and creates a new commit with the resulting content. It is considered to be a “safe” way of undoing changes because this operation doesn’t change the commit history.
This is the command you want to use when you need to fix a specific public (shared among others) commit in your history.
Let’s say we made a commit and introduced some bad code into our application.
The content of our application file now looks like this:
So now if we want to revert the “bad” commit we run this command:
$ git revert c1196bd # hash of a bad commit
If we check git log now, we’ll see that a new commit was created:
And this commit reverted the changes of the “bad” commit:
git revert doesn’t change the commit history, it’s used for undoing commits which were already published to the public repository.
For reverting local changes there is the get reset command. It returns your project to the state of a commit you specify while removing all the commits made after that commit.
# undo all the commits after <commit>, but don't touch the index nor remove the changes made to the repository after the <commit> $ git reset --soft <commit> # undo all the commits after <commit>, reset the index, but don't remove the changes made to the repository after the <commit> $ git reset <commit> # Completely undo all commits and changes after the <commit> $ git reset --hard <commit>
Git reset alters the history, which is why it’s considered to be dangerous and should never be used to reset commits that have already been published to the origin (which means other team members may base their work on that).
revert is meant to undo public commits,
reset is for local changes which were not pushed to a public repository.
If you’re experimenting on something locally and made a few commits that you wish to undo
git reset is the command to use.
For example, let’s reset the 3 last commits to completely remove our experimenting with
git revert command:
$ git reset --hard HEAD~3
If we now look for the file
app.py that was added 3 commits ago (see above screenshots), we are not going to find it, because our repository was restored to the state before this file was created.