0

I am trying to recover staged deleted files from my local branch. I tried git checkout file name, but it did not work. I don't want to use reset hard as it will reset all my required changes that I made to the other files. So is there a way to restore the deleted files only?

Hussein El Feky
  • 6,627
  • 5
  • 44
  • 57
sai
  • 17
  • 1
  • 1
  • 3

2 Answers2

0

There are several ways to do it. git reset <filename> should reset a single file only.

You can also do a git show HEAD:<filename> and save the output back to filename, then just git add it back in.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
0

Let's restate the question first.

Given this output from git status:

$ git status
On branch SOMEBRANCH
Your branch is up-to-date with ...

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    SOMEFILE

You now want to get file SOMEFILE back into both the work-tree and the index, so that the git status output will not say deleted: SOMEFILE.

Method 1: follow the advice git status gives

If you follow the advice that git status itself prints:

$ git reset HEAD SOMEFILE

the status will change to:

$ git status
On branch SOMEBRANCH
Your branch is up-to-date with ...

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    SOMEFILE

Now you have to take the advice shown again in git status:

$ git checkout -- SOMEFILE

Method 2 (short-cut)

The text just above Method 1 is the key to the short-cut. We want to copy the file SOMEFILE from the HEAD commit into the index, then copy the file SOMEFILE from the index into the work-tree. There is a command that does this: it's git checkout:

$ git checkout HEAD -- SOMEFILE

The trick is that when you say git checkout -- SOMEFILE, you are telling Git to copy the file only from the index to the work-tree.

This is why it takes two steps to do it the way git status suggests: the first step, git reset HEAD SOMEFILE, copies the file from the HEAD commit to the index. The second step, git checkout -- SOMEFILE, copies the file from the index to the work-tree. Using the git checkout HEAD -- SOMEFILE syntax we make Git copy from HEAD to index first, then from index to work-tree, all with one command.

(But the advice that git status gives works too.)

torek
  • 448,244
  • 59
  • 642
  • 775