Everyone who uses version control systems has to face the task of restoring a file at some point. Frequently, it must also be a file from several versions before. The built-in tools in Git allow such operations, but whoever uses them often knows that the –force flag when using git checkout or the git reset –hard command is handy. Let’s solve our problem once and for all.

In the case of Git, we know that we have the git checkout command at our disposal, and thanks to it, we can restore the file to the desired state using the script presented in Listing 1. The script presents various approaches to search for a change of interest and use the git checkout command. In the first and third approaches, we have to choose which commit is the target commit at some point. Thanks to this, we can find and select the most appropriate version, but it should be noted that we have to choose the correct change ourselves using the git log and git diff commands. You should also remember that we can restore with the command git ls-files -d | xargs git checkout files in a given folder. Here’s a little mystery, does this command work on deleted files with the git rm command? The truth is, however, that we don’t have to worry about such questions anymore because GitProtect is on the horizon!

$ git init
# We need to find here a change that interests us.
$ git log --diff-filter=D --summary
$ git checkout 9ad202d538c6ee6448e2c1ca1529f0e78edd3f86~1 -- kafej.xml

--or--

$ git init
# We will restore to the last version of the file here.
$ git rev-list -n 1 HEAD -- kafej.xml
$ git checkout 9ad202d538c6ee6448e2c1ca1529f0e78edd3f86~1 -- kafej.xml

--or--

$ git init
# find interesting us commit
$ git log
# review the changes made to a file
$ git diff 9ad202d538c6ee6448e2c1ca1529f0e78edd3f86 kafej.xml
$ git reset 9ad202d538c6ee6448e2c1ca1529f0e78edd3f86 kafej.xml --hard

Listing 1.Finding and restoring files with the git checkout command.

We must also remember that the git checkout command is not the only built-in tool in Git that will allow us to restore changes, files, etc. Another exciting command that we can use is git restore. Still, you have to remember that even the official Git documentation (can be found here) says that this tool is experimental, and you should never forget that. The name can be confusing, too, as using git restore is not used to undo changes to a repository but to undo local changes to a local disk. This means that we can, for example, undelete deleted files from the local disk from the repository, but not files in the repository itself. Keep this in mind and use the git checkout command, preferably GitProtect, if necessary.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
	(use "git push" to publish your local commits)

Changes are not staged for commit:
	(use "git add <file>..." to update what will be committed)
	(use "git restore <file>... " to discard changes in the working directory)
        	modified:   kafej.xml
$ git restore kafej.xml

Listing 2. Using the git restore command to restore a local file from a repository.

Another interesting tool is git revert, which will allow us to undo the changes and leave a note about them. This means that it will restore the changes from a given commit and at the same time make a new commit informing about this event. It is thanks to this property that this command is used very often. Thanks to this, we can keep documentation and information about our project according to actual events. This approach is very desirable and very similar to supporting Electronic Document Management (EDM), one of the main assumptions of complete transparency about changes in documents. This approach is mentioned as one of the best practices in creating projects.

$ git init
$ git add kafej.xml
$ git commit
hint: Waiting for your editor to close the file...
[master (root-commit) 0672413] Add file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 kafej.xml

$ git log
commit 06724135d660b9afbde334e61f98113349b52f48 (HEAD -> master)
Author: Kafej <michal.zbyl@gmail.com>
Date:   Sat May 29 16:55:14 2021 +0200

	Add file

$ git revert 06724135d660b9afbde334e61f98113349b52f48
Removing kafej.xml
hint: Waiting for your editor to close the file...
[master 8c9440d] Revert "Add file"
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 kafej.xml

$ git log
Author: Kafej <michal.zbyl@gmail.com>
Date:   Sat May 29 16:56:38 2021 +0200

	Revert "Add file"

	This reverts commit 06724135d660b9afbde334e61f98113349b52f48.

commit 06724135d660b9afbde334e61f98113349b52f48
Author: Kafej <michal.zbyl@gmail.com>
Date:   Sat May 29 16:55:14 2021 +0200

	Add file

Listing 3. An example of using the git revert command.

Okay, but is it not the case that all these commands can be confusing, and what if we use git reset –hard and understand that this isn’t the commit that we wanted after all. In such a case, let us have the GitProtect application, which will allow us to forget about all these commands and allow us and our programmers to develop the project, not the stress of undesirable changes in repositories.

Comments are closed.

You may also like