Tuesday, January 24, 2012

Git: Restore files deleted in older commits

Git is a Distributed Revision Control System. These four words seem familiar, but provide a powerful mechanism when all of them come together and Git is its resultant.

However well an application may be documented, it does not satisfy all the queries.

One such query I came across in my work was "How to retrieve the files those were deleted in older commits and not just the latest commit"

Below are the two ways to do that. First is the one what I prefer and the second one is recommended by a friend.

Consider, 3 commits have been made

Commit 1 : Initial Commit, Commit A. Files to be restored reside in this commit.
Commit 2 : deleted files say, A.txt and B.txt which has been committed as Commit B
Commit 3 : Made few Changes and committed as Commit C and many commits done so on.

Problem: Retrieve files A.txt and B.txt to current Head.

Solution:

First Method:

  1. List all the files those were deleted irrespective of the commits in which they were made.
$ git log --diff-filter=D --summary

          results as follows: SHA-1 of commit in which the delete of files A.txt and B.txt was committed, commit message, deleted files etc.



      2.     Find the SHA-1 of commit which last contained the files i.e. Commit just previous to the one listed in Step 1.


            Use $ git log command. In our eg, the log for 3 commits with their respective SHA-1's look as follows:




In our example, the commit which contains our files is 1bf2d..., say source to retrieve files from.


      3.  Restore the files

Use $ git checkout <revision> file.ext
  • revision : SHA-1 of source commit
  • file.ext : file name and path from where to retrieve.(Files are retrieved to their older path and not to new place. Of course, you can move them through Cut-Paste once restore.)


       4.  Do not forget to commit once the files are restored. In our eg after commit, the directory listing shows that the files are restored. The above snap shows that listing and deleted files A.txt and B.txt are restored back to same location.

Second Method:
  1. Use $ git log know the SHA1 commit versions.
  2. Check out the commit which contains the files you want to retrieve. Now, you will find the deleted files in the directory. Copy them to a temporary location.
  3. Now, again checkout to the latest commit i.e. Get back to the same place where you were before Step 2.
  4. Add the files to their respective directories from the temporary location.
  5. And, finally commit and list the directory to find the files.
Which method is better?

Both methods have upper hand depending on the situation and requirements.
  • If you want to restore the files to some new locations other than from where they were originally deleted, second method is good. However, you can use first method and then change file locations.
  • If you want the files to restore to same locations, first method is good. Ofcourse, with second method also you can do it. But, the overhead of copying files to temporary locations is eliminated in first method.
  • I would recommend the first method because the checking out to previous without committing the current may result in loosing your work yet to be committed for current verison.
Hope, this article has helped you and served the purpose for which you have visited this page.

Do post your feedbacks. Thats encouraging.

4 comments:

  1. Anshuma,
    This is pretty useful post for any one who uses GIT.

    ReplyDelete
  2. HI Anshuma.. Very nice and useful post. Good going keep it up and regularly come up with such more posts...:) N try this also.

    ReplyDelete
  3. Hi aj really awesome very helpful go on with developing the blog thanx all the very best

    ReplyDelete