Say I'm in a Git repository. I delete a file and commit that change. I continue working and make some more commits. Then, I discover that I need to restore that file after deleting it.
I know I can checkout a file using git checkout <commit> -- filename.txt
, but I don't know when that file was deleted.
git log --diff-filter=D -- path/to/file
- anyone git checkout deletedFile
will undelete deletedFile
if it's been deleted but that deletion has not yet been staged or committed. That's not what the question here is asking for; this question is about how to restore a file whose deletion was committed many commits ago. - anyone Find the last commit that affected the given path. As the file isn't in the HEAD commit, that previous commit must have deleted it.
git rev-list -n 1 HEAD -- <file_path>
Then checkout the version at the commit before, using the caret (^
) symbol:
git checkout <deleting_commit>^ -- <file_path>
Or in one command, if $file
is the file in question.
git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"
If you are using zsh and have the EXTENDED_GLOB option enabled, the caret symbol won't work. You can use ~1
instead.
git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"
Answered 2023-09-20 20:19:53
± git checkout $(git rev-list -n 1 HEAD "spec/Sporkfile_example.rb")^ -- "spec/Sporkfile_example.rb" zsh: no matches found: b71c152d8f38dcd23ad7600a93f261a7252c59e9^
I switched to bash & it worked fine though. - anyone error: pathspec <filename> did not match any file(s) known to git.
. The solution was to use git bash. - anyone git checkout <deleting-commit>~1 -- <file-path>
~X allows you to specify X commits before the specified commit, so ~1 is the commit before, ~2 is two commits before, etc - anyone ^
character is the escape character! Therefore, on cmd, you have to type ^^
to tell cmd you want a single literal ^ and that your not escaping something else after it. What's happening to many people is that the ^
is followed by a space. So cmd thinks you're escaping the space -- which yields simply a space character. Thus, by the time git gets the cli arguments, it sees SHA1
and not SHA1^
. It's really annoying. ~
isn't an escape character, so that's why that still works. (PS. if you think googlers will want this info, please upvote this comment) - anyone Get all the commits which have deleted files, as well as the files that were deleted:
git log --diff-filter=D --summary
Make note of the desired commit hash, e.g. e4e6d4d5e5c59c69f3bd7be2
.
Restore the deleted file from one commit prior (~1
) to the commit that was determined above (e4e6d4d5e5c59c69f3bd7be2
):
git checkout e4e6d4d5e5c59c69f3bd7be2~1 path/to/file.ext
Note the ~1
. The tilde spec will give you the nth grandparent of the named commit.
Answered 2023-09-20 20:19:53
git checkout $commit~1 filename
syntax works perfect for individual files, and also works for whole directories. ie: to restore all deleted images in ./images from sha 12345: git checkout 12345~1 images
. thanks for this answer! - anyone git show $commit~1:$path
- anyone ~1
or ^
does: gets the commit before deletion - anyone To restore all deleted files in a folder:
git ls-files -d | xargs git checkout --
Answered 2023-09-20 20:19:53
git
has made even the simplest task. - anyone ls-files
sub-command is handy, but doesn't seem to work for files that had been removed with git rm
i.e. staged, let alone committed, which is what the OP asked. - anyone git
is nearly unparalleled in its usefulness, while also imfamously complicated to learn. An appreciable proportion of git
s learning curve is due to an inconsistent / unintuitive UI. Personally, when I'm learning something difficult, one of the things that gives me reassurance is seeing that other (competent) people also struggled to figure it out - anyone If you deleted a file that exists in the latest HEAD
commit, you can restore it using:
git checkout HEAD -- path/to/file.ext
Answered 2023-09-20 20:19:53
If you’re insane, use git-bisect
. Here's what to do:
git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>
Now it's time to run the automated test. The shell command '[ -e foo.bar ]'
will return 0 if foo.bar
exists, and 1 otherwise. The "run" command of git-bisect
will use binary search to automatically find the first commit where the test fails. It starts halfway through the range given (from good to bad) and cuts it in half based on the result of the specified test.
git bisect run '[ -e foo.bar ]'
Now you're at the commit which deleted it. From here, you can jump back to the future and use git-revert
to undo the change,
git bisect reset
git revert <the offending commit>
or you could go back one commit and manually inspect the damage:
git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .
Answered 2023-09-20 20:19:53
git bisect run '[ -e foo.bar ]'
? - anyone git bisect run
tells Git to automate bisection by running the command following word 'run' where the command must return 0
for a good
version (see git help bisect
for details). The '[ -e foo.bar ]'
is a standard expression for testing if file foo.bar
does exists (the implementation is usually in file /usr/bin/[
which is usually hardlinked to /usr/bin/test
) and the single quation marks are used to put that all as a single command line argument. - anyone My new favorite alias, based on bonyiii's answer (upvoted), and my own answer about "Pass an argument to a Git alias command":
git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep '^D' | cut -f 2); }; f'
I have lost a file, deleted by mistake a few commits ago?
Quick:
git restore my_deleted_file
Crisis averted.
Warning, with Git 2.23 (Q3 2019) comes the experimental command named git restore
(!).
So rename this alias (as shown below).
Robert Dailey proposes in the comments the following alias:
restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"
And jegan adds in the comments:
For setting the alias from the command line, I used this command:
git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\""
Answered 2023-09-20 20:19:53
restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"
- anyone git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\""
- anyone Expansion of alias 'restore' failed; '!git' is not a git command
- anyone If you know the filename, this is an easy way with basic commands:
List all the commits for that file.
git log -- path/to/file
The last commit (topmost) is the one that deleted the file. So you need to restore the second to last commit.
git checkout {second to last commit} -- path/to/file
Answered 2023-09-20 20:19:53
To restore a deleted and commited file:
git reset HEAD some/path
git checkout -- some/path
It was tested on Git version 1.7.5.4.
Answered 2023-09-20 20:19:53
error: pathspec 'foo' did not match any file(s) known to git.
I made sure that the filename was correct. Git version 2.7.0 - anyone git add -A
, but so the restored file was still in non committed stage. - anyone I've got this solution.
Get the id of the commit where the file was deleted using one of the ways below.
git log --grep=*word*
git log -Sword
git log | grep --context=5 *word*
git log --stat | grep --context=5 *word*
# recommended if you hardly
remember anythingYou should get something like:
commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 Author: Alexander Orlov Date: Thu May 12 23:44:27 2011 +0200
replaced deprecated GWT class - gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script
commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302 Author: Alexander Orlov Date: Thu May 12 22:10:22 2011 +0200
3. Now using the commit id bfe68bd117e1091c96d2976c99b3bcc8310bebe7 do:
git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java
As the commit id references the commit where the file was already deleted you need to reference the commit just before bfe68b which you can do by appending ^1
. This means: give me the commit just before bfe68b.
Answered 2023-09-20 20:19:53
If you only made changes and deleted a file, but not commit it, and now you broke up with your changes
git checkout -- .
but your deleted files did not return, you simply do the following command:
git checkout <file_path>
And presto, your file is back.
Answered 2023-09-20 20:19:53
Actually, this question is directly about Git, but somebody like me works with GUI tools like the WebStorm VCS other than knowing about Git CLI commands.
I right click on the path that contains the deleted file, and then go to Git and then click on Show History.
The VCS tools show all revisions train and I can see all commits and changes of each of them.
Then I select the commits that my friend delete the PostAd.js
file. now see below:
And now, I can see my desire deleted file. I just double-click on the filename and it recovers.
I know my answer is not Git commands, but it is fast, reliable and easy for beginner and professional developers. WebStorm VCS tools are awesome and perfect for working with Git and it doesn't need any other plugin or tools.
Answered 2023-09-20 20:19:53
git undelete path/to/file.ext
Put this in your .bash_profile
(or other relevant file that loads when you open a command shell):
git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
Then use:
git undelete path/to/file.ext
This alias first checks to find the last commit where this file existed, and then does a Git checkout of that file path from that last commit where this file existed. Source.
Answered 2023-09-20 20:19:53
git checkout /path/to/deleted.file
Answered 2023-09-20 20:19:53
In many cases, it can be useful to use coreutils (grep, sed, etc.) in conjunction with Git. I already know these tools quite well, but Git less so. If I wanted to do a search for a deleted file, I would do the following:
git log --raw | grep -B 30 $'D\t.*deleted_file.c'
When I find the revision/commit:
git checkout <rev>^ -- path/to/refound/deleted_file.c
Just like others have stated before me.
The file will now be restored to the state it had before removal. Remember to re-commit it to the working tree if you want to keep it around.
Answered 2023-09-20 20:19:53
I had the same question. Without knowing it, I had created a dangling commit.
List dangling commits
git fsck --lost-found
Inspect each dangling commit
git reset --hard <commit id>
My files reappeared when I moved to the dangling commit.
git status
for the reason:
“HEAD detached from <commit id where it detached>”
Answered 2023-09-20 20:19:53
Find the commit that deleted your file:
git log --diff-filter=D --oneline -- path/to/file | cut -f -d ' '
Sample output:
4711174
As of Git 2.23 there is actually a restore
command. It is still experimental but in order to restore something you removed in a commit (4711174 in this case) you can then type:
git restore --source=4711174^ path/to/file
Note the ^ after the commit id as we want to restore something from the commit before the one that deleted the file.
The --source
argument tells the restore
command where to look for the file(s) to restore and it can be any commit and even the index.
Answered 2023-09-20 20:19:53
git log --diff-filter=D --oneline -- path/to/file | cut -d ' ' -f 1
- anyone I had to restore a bunch of deleted files from a specific commit, and I managed it with two commands:
git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git checkout <rev>^ --
git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git reset HEAD
(Note the trailing space on the end of each command.)
The files had been added to the .gitignore file and then cleared with git rm
. I needed to restore the files, but then unstage them. I had hundreds of files to restore, and typing things manually for each file as in the other examples was going to be far too slow.
Answered 2023-09-20 20:19:53
user@bsd:~/work/git$ rm slides.tex
user@bsd:~/work/git$ git pull
Already up-to-date.
user@bsd:~/work/git$ ls slides.tex
ls: slides.tex: No such file or directory
Restore the deleted file:
user@bsd:~/work/git$ git checkout
D .slides.tex.swp
D slides.tex
user@bsd:~/work/git$ git checkout slides.tex
user@bsd:~/work/git$ ls slides.tex
slides.tex
Answered 2023-09-20 20:19:53
In our case we accidentally deleted files in a commit and some commits later we realized our mistake and wanted to get back all the files that were deleted, but not those that were modified.
Based on Charles Bailey's excellent answer, here is my one-liner:
git co $(git rev-list -n 1 HEAD -- <file_path>)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- <file_path>)~1 head | grep '^D' | cut -f 2)
Answered 2023-09-20 20:19:53
Plus point: The below methods does work good for the scenario that files/folders got deleted even from your Trash or Recycle bin.
I. If you have not yet indexed (git add) your changes you can revert content of a directory:
git restore -- path/to/folder_OR_file
II. If the deletion is already indexed, you should reset that first:
git reset -- path/to/folder_OR_file
then perform, git restore path/to/folder_OR_file
git log --diff-filter=D --summary
to get details of the commits in which files/folder were deleted;git checkout $commit~1 path/to/folder_OR_file
to restore the deleted files/folder.
Where $commit
is the sha-value of the commit you've found at step 1, e.g. c7578994Answered 2023-09-20 20:19:53
If you know the commit that deleted the file(s), run this command where <SHA1_deletion>
is the commit that deleted the file:
git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --
The part before the pipe lists all the files that were deleted in the commit; they are all checkout from the previous commit to restore them.
Answered 2023-09-20 20:19:53
For the best way to do that, try it.
First, find the commit id of the commit that deleted your file. It will give you a summary of commits which deleted files.
git log --diff-filter=D --summary
git checkout 84sdhfddbdddf~1
Note: 84sdhfddbddd
is your commit id
Through this you can easily recover all deleted files.
Answered 2023-09-20 20:19:53
Simple and precise-
First of all, get a latest stable commit in which you have that file by -
git log
Say you find $commitid 1234567..., then
git checkout <$commitid> $fileName
This will restore the file version which was in that commit.
Answered 2023-09-20 20:19:53
This is the easiest solution I found if you want just restore the same file in master:
git checkout master -- path/to/File.java
Answered 2023-09-20 20:19:53
You could always git revert
your commit which deleted the file. (This assumes that the deletion was the only change in the commit.)
> git log
commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3
Author: Dave <dave@domain.com>
Date: Thu May 9 11:11:06 2019 -0700
deleted readme.md
And if you've continued work, and realized later that you didn't want to commit that deletion commit, you could revert it using:
> git revert 2994bd
Now git log
shows:
> git log
Author: Dave <dave@domain.com>
Date: Thu May 9 11:17:41 2019 -0700
Revert "deleted readme"
This reverts commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3.
And readme.md
has been restored into the repository.
Answered 2023-09-20 20:19:53
If the deletion has not been committed, the command below will restore the deleted file in the working tree.
$ git checkout -- <file>
You can get a list of all the deleted files in the working tree using the command below.
$ git ls-files --deleted
If the deletion has been committed, find the commit where it happened, then recover the file from this commit.
$ git rev-list -n 1 HEAD -- <file>
$ git checkout <commit>^ -- <file>
In case you are looking for the path of the file to recover, the following command will display a summary of all deleted files.
$ git log --diff-filter=D --summary
Answered 2023-09-20 20:19:53
I also have this problem using the below code to retrieve a previous file to a local directory:
git checkout <file path with name>
The below example is working for me:
git checkout resources/views/usaSchools.blade.php
Answered 2023-09-20 20:19:53
You can checkout deleted files:
git checkout
Output
D index.html
To restore it:
git restore index.html
If you deleted multi files and you need to restore all use:
git restore .
Answered 2023-09-20 20:19:53
$ git log --diff-filter=D --summary | grep "delete" | sort
Answered 2023-09-20 20:19:53
In order to restore all deleted file with Git, you can also do:
git checkout $(git ls-files --deleted)
Where git ls-files --deleted
lists all deleted files and git checkout $(git command)
restores the list of files in a parameter.
Answered 2023-09-20 20:19:53