As a developer, you would have across such situations multiple times where you would have wanted to roll back to one of your previous commits but not sure how to do that. And even if you know the Git commands like reset, revert, rebase, you are not aware of the differences between them. So let’s get started and understand what git reset, revert and rebase are.

Git Reset

Git reset is a complex command, and it is used to undo the changes. You can think of git reset as a rollback feature. With git reset, you can jump between various commits. There are three modes of running a git reset command: –soft, –mixed, and –hard. By default, git reset command uses the mixed mode. In a git reset workflow, three internal management mechanisms of git come into the picture: HEAD, staging area (index), and the working directory.

The working directory is the place where you are currently working, it is the place where your files are present. Using a git status command, you can see what all files/folders are present in the working directory. Staging Area (Index) is where git tracks and saves all the changes in the files. The saved changes are reflected in the .git directory. You use git add “filename” to add the file to the staging area. And like before, when you run git status, you will see which files are present in the staging area. The current branch in Git is referred to as HEAD. It points to the last commit, which happened in the current checkout branch. It is treated as a pointer for any reference. Once you checkout to another branch, the HEAD also moves to the new branch. Let me explain how git reset works in hard, soft, and mixed modes. Hard mode is used to go to the pointed commit, the working directory gets populated with files of that commit, and the staging area gets reset. In soft reset, only the pointer is changed to the specified commit. The files of all the commits remain in the working directory and staging area before the reset. In mixed mode (default), the pointer and the staging area both get reset.

Git Reset Hard

The purpose of git hard reset is to move the HEAD to the specified commit. It will remove all the commits with happened after the specified commit. This command will change the commit history and point to the specified commit. In this example, I will add three new files, commit them and then perform a hard reset. As you can see from the command below, right now, there is nothing to commit. Now, I will create 3 files and add some content to it. Add these files to the existing repository. When you rerun the status command, it will reflect the new files I just created. Before committing, let me show you, I currently have a log of 3 commits in Git. Now, I will commit to the repository. If I do ls-files, you will see the new files have been added. When I run the log command in git, I have 4 commits, and the HEAD points to the latest commit. If I go and delete the file1.txt manually and do a git status, it will show the message that the changes are not staged for commit. Now, I will run the hard reset command. If I recheck the status, I will find there is nothing to commit, and the file I deleted has come back into the repository. The rollback has happened because after deleting the file, I did not commit, so after a hard reset, it went back to the previous state. If I check the log of git, this is how it will look. The purpose of hard reset is to point to the specified commit and update the working directory and staging area. Let me show you one more example. Currently, the visualization of my commits looks like below:

Here, I will run the command with HEAD^, which means I want to reset to the previous commit (one commit back). You can see the head pointer has now changed to 0db602e from d69950b.

If you check the log, the commit of d69950b is gone, and the head now points to 0db602e SHA. If you run the ls-files, you can see file1.txt, file2.txt, and files3.txt are not in the repository anymore because that commit and its file got removed after the hard reset.

Git Soft Reset

Similarly, now I will show you an example of a soft reset. Consider, I have added the 3 files again as mentioned above and committed them. The git log will appear as shown below. You can see ‘soft reset’ is my latest commit, and HEAD is also pointing to that. Details of the commit in the log can be seen using the below command. Now using the soft reset, I want to switch to one of the older commits with SHA 0db602e085a4d59cfa9393abac41ff5fd7afcb14 To do that, I will run the below command. You need to pass more than 6 starting characters of SHA, the complete SHA is not required. Now when I run the git log, I can see the HEAD has been reset to the commit I specified. But the difference here is, the files of the commit (aa400858aab3927e79116941c715749780a59fc9) where I had added 3 files are still in my working directory. They have not got deleted. That’s why you should use a soft reset rather than a hard reset. There is no risk of losing the files in the soft mode.

Git Revert

In Git, the revert command is used to perform a revert operation, i.e., to revert some changes. It is similar to the reset command, but the only difference here is that you perform a new commit to go back to a particular commit. In short, it is fair to say that the git revert command is a commit. The Git revert command does not delete any data while performing the revert operation. Let’s say I am adding 3 files and performing a git commit operation for the revert example. The log will show the new commit. Now I would like to revert to one of my past commits, let’s say – “59c86c9 new commit”. I would run the command below. This will open a file, you will find the details of the commit you are trying to revert to, and you can give your new commit a name here, and then save and close the file. After you save and close the file, this is the output you will get. Now to make the necessary changes, unlike reset, revert has performed one more new commit. If you check the log again, you will find a new commit because of the revert operation.

Git log will have all the history of commits. If you want to remove the commits from the history, then revert is not a good choice, but if you want to maintain the commit changes in the history, then revert is the suitable command instead of reset.

Git Rebase

In Git, rebase is the way of moving or combining commits of one branch over another branch. As a developer, I would not create my features on the master branch in a real-world scenario. I would work on my own branch (a ‘feature branch’), and when I have a few commits in my feature branch with the feature added, I would then like to move it to the master branch. Rebase can sometimes be a little confusing to understand because it is very similar to a merge. The goal of merging and rebasing both is to take the commits from my feature branch and put them on to a master branch or any other branch. Consider, I have a graph which looks like this:

Suppose you are working in a team with other developers. In that case, you can imagine that this could get really complex where you have a bunch of other developers working on different feature branches, and they have been merging multiple changes. It becomes confusing to trace. So, this is where rebase is going to help. This time, instead of doing a git merge, I will do a rebase, where I want to take my two feature branch commits and move them onto the master branch. A rebase will take all my commits from the feature branch and move them on top of the master branch commits. So, behind the scenes, git is duplicating the feature branch commits on the master branch.

This approach will give you a clean straight-line graph with all the commits in a row.

It makes it easy to trace what commits went where. You can imagine if you are on a team with many developers, all the commits are still in a row. So, it is really easy to follow even if you have many people working on the same project at the same time. Let me show you this practically. This is how my master branch looks like currently. It has 4 commits. I will run the below command to create and switch to a new branch called feature, and this branch will be created from the 2nd commit, i.e. 59c86c9 If you check the log in the feature branch, it has only 2 commits coming from the master (mainline). I will create feature 1 and commit it to the feature branch. I will create one more feature, i.e., feature 2, in the feature branch and commit it. Now, if you check the log of the feature branch, it has two new commits, which I executed above. Now I want to add these two new features to the master branch. For that, I will use the rebase command. From the feature branch, I will rebase against the master branch. What this will do is it will re-anchor my feature branch against the latest changes. Now I am going to go ahead and checkout the master branch. And finally, rebase the master branch against my feature branch. This will take those two new commits on my feature branch and replay them on top of my master branch. Now if I check the log on the master branch, I can see the two commits of my features branch have been added to my master branch successfully. That was all about reset, revert and rebase commands in Git.

Conclusion

That was all about reset, revert and rebase commands in Git. I hope this step-by-step guide was helpful. Now, you know how to play around with your commits as per the need using the commands mentioned in the article.

Git Reset vs Revert vs Rebase - 1Git Reset vs Revert vs Rebase - 78Git Reset vs Revert vs Rebase - 47Git Reset vs Revert vs Rebase - 89Git Reset vs Revert vs Rebase - 60Git Reset vs Revert vs Rebase - 22Git Reset vs Revert vs Rebase - 34Git Reset vs Revert vs Rebase - 57Git Reset vs Revert vs Rebase - 19Git Reset vs Revert vs Rebase - 63Git Reset vs Revert vs Rebase - 59Git Reset vs Revert vs Rebase - 50Git Reset vs Revert vs Rebase - 36