Published on

Reverting a particular committed file to a previous version in Git

Last Modified on
Last modified on
Authors

I just made some changes to a file and then committed them so I could have a reference of those changes in my Git history, but I knew that I wanted to revert back to the prior version of the file.

I knew that I needed the object id of the file from the last commit I had made, but how was I to get it?

It was really simple. The following is the command I ran:

git rev-parse where-to-put-our-logic:src/components/Shop/ProductItem.js

And the command returned the following:

243d68e5d39018d368391ffdff9ea886484e13da

which was the hash for that particular file in the commit I had previously made in the where-to-put-our-logic branch.

git rev-parse is the command. where-to-put-our-logic is the name of the branch, and where I made the commit. src/components/Shop/ProductItem.js is the relative path to the file I needed the object id of.

However, I wanted to get the latest id of the file in the master branch, which is where I merged the latest commits into. So I needed to get the hash of the latest commit which contained the version of the file I wanted.

First I ran the git log --oneline command. This logs a list of all the commits made in the local repository.

git log shows a list of all the commits made to a repository. There, we can see the hash of each Git commit, the message associated with each commit (one reason why good commit messages are important, to remind us what we did with the code, for example, in that commit), and more metadata. This command is useful for displaying the history of a repository.

Below is the --oneline I was looking for in the results returned from running the git log —online command:

e5f52f0 (origin/main, main) Merge branch 'refresher-practice-2'

The message here refers to the fact that I had merged the refreshed-practice-2 branch into the main branch, so even though it was a default message, it still was informative, and the commit hash I wanted. Then, in order to revert the content of the file to that commit, I ran the following command:

git reset e5f52f0 src/components/Shop/ProductItem.js

And the following was returned in the Terminal console:

Unstaged changes after reset:
M       src/components/Shop/ProductItem.js

Then I ran git status to see what the status was of that file:

git status

And I got back the following in the Terminal console:

git status
On branch where-to-put-our-logic
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/components/Shop/ProductItem.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/components/Shop/ProductItem.js

Then I ran the following command:

git checkout src/components/Shop/ProductItem.js

And got the following back in the Terminal console:

Updated 1 path from the index

Then again, I ran git status, and got back the following in the Terminal console:

git status
On branch where-to-put-our-logic
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/components/Shop/ProductItem.js

So I staged the reverted changes of the file. I was not sure whether I wanted to do that or not, but I ran the following command:

git restore --staged src/components/Shop/ProductItem.js

As prompted by the information returned to the Terminal console when I ran git status (right above). Then I ran git status again, and got the following back:

On branch where-to-put-our-logic
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/components/Shop/ProductItem.js

no changes added to commit (use "git add" and/or "git commit -a")

Since the content of the file was the same when I had staged the reverted changes and now, when I had unstaged those changes, but they were still present, I could have just skipped

git restore --staged src/components/Shop/ProductItem.js

and just committed the changes. But since I had unstaged the reverted changes, I had to do the following:

git add src/components/Shop/ProductItem.js

And then:

git commit

And the following was returned to the Terminal console after I created my commit message in VIM and was taken back to my where-to-put-our-logic branch:

git commit
[where-to-put-our-logic aa33ca2] Add back original code
 1 file changed, 13 insertions(+), 49 deletions(-)

[where-to-put-our-logic aa33ca2] refers to the branch I am on followed by the hash of the new commit I just made. And Add back original code is the commit message I created in VIM.

1 file changed, 13 insertions(+), 49 deletions(-) just lets me know that 1 file was changed, 13 additions and 49 deletions made to the file.

I had a second file in the same project that I wanted to revert back to the version in the same (previous) commit, so I followed the steps I made the first time around.

I wanted to revert back to the previous version of a file with the relative path src/store/cart-slice.js, so I first ran the following command in Terminal inside the root of the project:

git reset e5f52f0 src/store/cart-slice.js

And when I hit return, I got the following back in the Terminal console:

Unstaged changes after reset:
M       src/store/cart-slice.js

Then I ran git status, and the following was returned in the Terminal console:

git status
On branch where-to-put-our-logic
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/store/cart-slice.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/store/cart-slice.js

And when I checked at this point to see if the file content had changed yet, it had not. So then I knew I had to go through all the steps I had taken with the previous file.

So next, as before, I ran

git checkout src/store/cart-slice.js

And it is with this command that the content of the file reverted back to the version in the commit with the hash of e5f52f0. So what is happening here, is I removed all the pre-commit changes that had been made to the file, after I had reset it to the commit I wanted. And the following was returned to the Terminal console:

git status
On branch where-to-put-our-logic
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/store/cart-slice.js

So checking out the file staged it, and with the version of the code that I wanted. So then I ran the following command in Terminal:

git commit

And I was taken into VIM to write my commit message. And when I returned to the where-to-put-our-logic branch, and ran git status, I got back the following:

On branch where-to-put-our-logic
nothing to commit, working tree clean

Which is exactly what I wanted! I found that I did not have to run the git restore command. That was overkill.

I also wrote a post entitled Removing unstaged changes to your individual files in Git, which you might want to check out as well.

Happy Git version control!