Git is a well-known version control system used by the majority of developers and organizations.
While making commits to the git repository there might be some accidental commits involving unintended changes or deletion of files.
In such a case, we can easily undo commits or changes with the help of a few git commands. Undoing git commits can be done in various methods based on how we wanted to keep the git history.
In this article, we're going to see those different methods to git undo commits.
Before actually diving into it, let's initialize git and commit a few files, so that we can use that to look into various git reverting commands.
Go to your favorite command line tool and run the below commands. Make sure that you have installed git in your system.
# In the folder where you want to have a git repo
> git init
> echo One > one.txt; echo Two > two.txt; echo Three > three.txt; # Creating three files
> git add one.txt
> git commit -m "Adds one.txt"
> git add two.txt
> git commit -m "Adds two.txt"
> git add three.txt
> git commit -m "Adds three.txt"
> git log --online
bdb52f3 (HEAD -> master) Adds three.txt
c387fcb Adds two.txt
e99f4bf Adds one.txt
Let's make some changes to a file and commit it.
# Making changes to one.txt
> echo Edited one > one.txt
> git commit -am "Updates one.txt" # Adding and committing directly
> git log --oneline
8b730e8 (HEAD -> master) Updates one.txt
bdb52f3 Adds three.txt
c387fcb Adds two.txt
e99f4bf Adds one.txt
Now let's see how to git undo the last commit.
4 ways to git undo last commit
1. Using git revert
git revert
command does the same as it states, that is it reverts any committed changes. This git command reverts the specified commit and creates a new commit with the reverted changes.
This is the most preferred git command for undoing or reverting any commits because this doesn't delete or orphan any of the commits. In short, this command doesn't rewrite the git history.
Let's see how to undo the commit using git revert
command
# Undoing the last commit using git revert
> git revert HEAD
To revert the last commit, we can use HEAD as it points to the last commit or we can use the hash of the commit we want to undo. By running the above command opens the configured editor to change the default message and once you close the editor, the last commit gets reverted with a new commit having "Revert" prefix to the actual commit name.
To avoid the editor from opening you can use --no-edit
flag. To avoid committing the changes you can use -n
or --no-commit
flag as a result the reverted changes will be added to the staging(index) area without committing it.
# Reverting without opening the editor
> git revert --no-edit HEAD
# Reverting without committing the reverted changes
> git revert -n HEAD
Now let's see another way to git undo last commit.
2. Using git reset
The git reset is a powerful command using which we can undo a series of previously committed changes. This command orphans the commits by resetting the head to a specified state.
git reset
takes the commit hash or reference from HEAD to which it is going to reset to. Once the git reset command is run, there won't be any latest commit logs up to the commit hash.
We can undo the last commit in three different forms with the git reset
command. There are three flags that can be used with this command, --soft, --mixed(default), --hard.
On --soft
reset, the commit gets removed and the changes get added to the staging area.
On --mixed
reset(default), the commit gets removed and the changes get added to the local or working area.
On --hard
reset, the commit gets removed and all the changes would be lost.
So based on your requirement you can pick the appropriate flag to undo the last commit.
# Undoing the last commit using git reset
> git reset HEAD^ # points to the commit before the last one
# To completely undo the commit
> git reset --hard HEAD^
Now let's see the third way to undo the last git commit.
3. Using git restore
The git restore
command is used to restore files in the working directory from the index or from other commits. We can also restore files to the index from other commits.
git restore
will not remove the previous commit logs or messages, it just restores the files or the directories as before.
# Restoring the working directory from index
> git restore . # .(dot) means complete directory
The above command just restores everything from the last commit. But what we want is to restore the commit before the last commit.
To restore files from other commits, git restore has --source
flag, using that we can restore the parent of the last commit i.e., HEAD~1.
# Undoing the last commit using git restore
> git restore --source=HEAD~1 .
By running the above command, the working directory will be with changes as that of the last commit's parent. It's just like git revert -n HEAD
result but all the changes will be in the working directory not in the staging area.
To restore the changes to the staging area just use the --staged
flag.
So using git restore
command you will have the flexibility to commit changes with any message unlike git revert default message and also you can restore files specifically instead of the whole directory.
And now let's see the fourth way to undo the last git commit.
4. Using git rebase -i
The git rebase -i
is a very powerful command for rewriting the git history. This command is used for rewording, editing, picking, dropping, squashing, etc commits.
git rebase with interactive flag helps to drop the commits. The same feature we can use to undo the last commit.
To make changes to the commit using rebase -i
we need to go(rebase) to the parent of that commit and then make any changes we want.
# Undoing the last commit using git rebase
> git rebase -i HEAD~1 # select d - drop from the menu and proceed
When you run the above command your default editor gets opened with a list of actions you can perform on the last commit, select d
or drop
option and proceed. That will remove the last commit from the git log.
And that is how you can undo last git commit using rebase -i.
Points to note
git revert
and git restore
will not modify the git history or log. So when dealing with collaborative works, it's good to use git revert and git restore for undoing the commits. This will help to maintain a clear log of all actions.
git reset
and git rebase -i
will remove the logs of the commits. You can prefer this when your commits are local but in collaborative cases, you should strictly avoid using these because by chance you may end up rewriting the history of other people's commits.
Those are all the methods one can use to undo git commits. Which method to use depends on the individuals and their work environment.