In this article I will walk through how to do a git reset hard. When working with git on a project with multiple developers there tends to be a lot of changes to the code repository. Branches are created, files are added and changed, and files are staged and committed. With this amount of activity sometimes changes are made to files in the project which do not have the desired result, leading to you needing to revert the changes and roll back to a previous version of the code.
With Git being a version control system (specifically a distributed VCS), previous versions of files in the project are available. Read on to find out how to undo your changes in git using a git hard reset.
Types of Git Reset
There are a few different ways you can run a git reset. It’s important to know the implications of each one.
git reset --soft
, this will keep your files, and stage all changes back automatically.git reset --hard
, which will remove any changes and remove them from the local directory. Be fully sure of what the impact of running this one is, use caution!git reset --mixed
, This keeps all files the same but unstages the changes.
Git Hard Reset Example
For this walk through I’ll be using a project containing some Terraform code which I have in a remote git repository. So the first thing I want to do is to clone the remote repository so that I can work with it locally:
$ git clone git@github.com:buildvirtual-git/test-repo.git
A quick directory listing using the ls command shows that the repo has been cloned successfully and that we have a copy of the project files in a local directory:
$ ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 19/01/2022 08:16 745 .gitignore
-a---- 05/01/2022 09:46 3120 main.tf
-a---- 24/11/2021 11:48 75 outputs.tf
-a---- 19/01/2022 08:16 11 README.md
-a---- 30/11/2021 11:05 345 terraform.tfvars
-a---- 24/11/2021 10:24 1080 variables.tf
Ok, so next we need to make a couple of changes and commits to this git branch. For my first commit I will create a new file called network.tf, then follow that commit by adding another file called storage.tf. This mimics common activities if I were working on developing a Terraform plan. These are the commands I used to create the new file then commit them:
$ echo "#network tf" >> network.tf
$ git add network.tf
$ git commit -m "added network.tf
I went through this a couple of times to build up a commit history for the purposes of this demo. We can see this commit history by checking the git log.
Note: Before you perform a git reset you will first need to check the git log so that you can get a list of all the previous commits in your git branch.
$ git log --oneline
eba9504 (HEAD -> main) added storage.tf
1264a9a added storage.tf
bcf4be1 added network.tf
237adf8 (origin/main, origin/HEAD) first commit
6bb851a Initial commit
Ok, so lets say we were developing these files locally, and after the latest commit I made some changes to the network.tf file and add a new database.tf as well. Now, during testing, these code updates didn’t work out as expected, and I need to go back to how things were when I made the network.tf commit. We can reset the git branch to an earlier point in time. We do this by using the git reset command to move the head back to an earlier commit. In this case I want to go back to where I added network.tf but before I added storage.tf, and made those other changes:
$ git reset bcf4be1 --hard
A –hard reset resets the index and working tree. Any changes to tracked files in the working tree since the commit are discarded. Any untracked files or directories in the way of writing any tracked files are simply deleted. Again, just to stress this can have a significant impact, so be careful to ensure you understand what the result of the reset will be!
If we do an ‘ls’ now, it looks like this:
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 19/01/2022 08:16 745 .gitignore
-a---- 05/01/2022 09:46 3120 main.tf
-a---- 19/01/2022 13:42 28 network.tf
-a---- 24/11/2021 11:48 75 outputs.tf
-a---- 24/11/2021 11:48 75 storage.tf
-a---- 19/01/2022 08:16 11 README.md
-a---- 30/11/2021 11:05 345 terraform.tfvars
-a---- 24/11/2021 10:24 1080 variables.tf
And, our git log now shows only 3 commits, with head now pointing to the commit where network.tf was added:
$ git log --oneline
bcf4be1 (HEAD -> main) added network.tf
237adf8 (origin/main, origin/HEAD) first commit
6bb851a Initial commit
Note that if we run a ‘git reflog‘ however, we still do have a history of the local system’s commits:
$ git reflog
bcf4be1 (HEAD -> main) HEAD@{0}: reset: moving to bcf4be1
bcf4be1 (HEAD -> main) HEAD@{1}: reset: moving to bcf4be1
eba9504 HEAD@{2}: commit: added storage.tf
1264a9a HEAD@{3}: commit: added storage.tf
bcf4be1 (HEAD -> main) HEAD@{4}: commit: added network.tf
237adf8 (origin/main, origin/HEAD) HEAD@{5}: commit: first commit
6bb851a HEAD@{6}: clone: from github.com:buildvirtual-git/test-repo.git
Effectively we have discarded all the updates made to the repository that took place after the network.tf commit. If we were to now push our updates to the remote repository, it will look like this:
Conclusion
In this tutorial, you have seen how to perform a git hard reset to reset changes in your git repository by using the “git reset –hard” command. Remember, a hard reset is destructive – it will discard changes when you reset to an earlier commit, affecting the files in your working directory. It’s a good idea to try the git commands mentioned here out in a test repository, so that you can get to grips with how the git reset command works until you are confident using it!