Как найти удаленный файл в git

I had this happen where I didn’t even know what the file’s name was, so I wanted to see all deleted files…

In general, I highly recommend becoming familiar with git-filter-repo. It has many uses for re-writing history, but one of its analysis features includes very quickly identifying all deleted files in a repo, and displaying their sizes and date deleted. (Using it on non-Windows OSes is fairly straight-forward, and here are installation instructions specifically for Windows.)

Once you have it runnable in your path, you simply run:

git filter-repo --analyze

This will output some files in your .git folder, and the one you want to look at for this question is called:

.gitfilter-repoanalysispath-deleted-sizes.txt

This file shows all deleted files in your repo, reverse sorted by size, and the date it was deleted. Here’s an example output:

=== Deleted paths by reverse accumulated size ===
Format: unpacked size, packed size, date deleted, path name(s)
    57151421   44898377 2022-07-22 somdirectory/somefileA
    46034619   42929136 2022-01-18 somdirectory/somefileB
    65332368   29102439 2020-09-28 somdirectory/somefileC
    23686432   21681498 2022-07-22 somdirectory/somefileD
    23681272   21678818 2022-07-22 somdirectory/somefileE
    23676153   21670502 2022-07-22 somdirectory/somefileF
    43232768   21439037 2020-07-10 somdirectory/somefileG
    18714315   14299243 2019-01-10 somdirectory/somefileH
    16788104   13035176 2019-01-10 somdirectory/somefileI

Obviously you can use this to find the file you’re looking for, or, in the context of re-writing history, based on the 2nd column sizes, I know if I remove those 9 deleted files from the history I’ll reclaim about 220 MB.

Once you’ve identified the file you’re looking for you can use this to find the commits:

git log --all --full-history -- <filename>

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"

xiota's user avatar

answered Jul 11, 2009 at 7:12

CB Bailey's user avatar

CB BaileyCB Bailey

744k102 gold badges631 silver badges655 bronze badges

20

  1. 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.

  2. 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 grandchild of the named commit . See http://book.git-scm.com/4_git_treeishes.html for more details

user's user avatar

user

13.7k6 gold badges25 silver badges112 bronze badges

answered Jun 4, 2009 at 23:10

Robert Munteanu's user avatar

Robert MunteanuRobert Munteanu

66.7k35 gold badges203 silver badges277 bronze badges

6

To restore all deleted files in a folder:

git ls-files -d | xargs git checkout --

Mateen Ulhaq's user avatar

Mateen Ulhaq

23.7k17 gold badges94 silver badges132 bronze badges

answered Dec 2, 2010 at 6:11

Manu's user avatar

ManuManu

4,0811 gold badge17 silver badges23 bronze badges

10

If you deleted a file that exists in the latest HEAD commit, you can restore it using:

git checkout HEAD -- path/to/file.ext

Mateen Ulhaq's user avatar

Mateen Ulhaq

23.7k17 gold badges94 silver badges132 bronze badges

answered Apr 10, 2014 at 0:03

Brett's user avatar

BrettBrett

4,0068 gold badges36 silver badges50 bronze badges

0

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 Jun 4, 2009 at 22:46

Josh Lee's user avatar

Josh LeeJosh Lee

169k38 gold badges268 silver badges274 bronze badges

5

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 Feb 17, 2013 at 15:33

VonC's user avatar

VonCVonC

1.2m513 gold badges4329 silver badges5142 bronze badges

15

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

Mark Amery's user avatar

Mark Amery

140k78 gold badges402 silver badges457 bronze badges

answered Feb 27, 2016 at 1:50

wisbucky's user avatar

wisbuckywisbucky

32.1k10 gold badges142 silver badges99 bronze badges

2

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.

Peter Mortensen's user avatar

answered Jul 4, 2012 at 4:39

Fedir RYKHTIK's user avatar

Fedir RYKHTIKFedir RYKHTIK

9,8046 gold badges57 silver badges67 bronze badges

3

I’ve got this solution.

  1. 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 anything
  2. You 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.

the Tin Man's user avatar

the Tin Man

158k41 gold badges214 silver badges302 bronze badges

answered Mar 1, 2012 at 10:48

Alex's user avatar

AlexAlex

8,1678 gold badges44 silver badges55 bronze badges

2

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 Sep 2, 2016 at 15:30

Paulo Linhares - Packapps's user avatar

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.

Enter image description here

The VCS tools show all revisions train and I can see all commits and changes of each of them.

Enter image description here

Then I select the commits that my friend delete the PostAd.js file. now see below:

Enter image description here

And now, I can see my desire deleted file. I just double-click on the filename and it recovers.

Enter image description here

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.

Peter Mortensen's user avatar

answered Nov 24, 2018 at 11:12

AmerllicA's user avatar

AmerllicAAmerllicA

27.9k15 gold badges126 silver badges152 bronze badges

2

git undelete path/to/file.ext

  1. 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" -'
    
  2. 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.

Peter Mortensen's user avatar

answered Jun 8, 2017 at 1:13

Beau Smith's user avatar

Beau SmithBeau Smith

32.9k13 gold badges94 silver badges101 bronze badges

0

git checkout /path/to/deleted.file

the Tin Man's user avatar

the Tin Man

158k41 gold badges214 silver badges302 bronze badges

answered Jun 25, 2013 at 19:40

user1528493's user avatar

user1528493user1528493

4314 silver badges5 bronze badges

2

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 $'Dt.*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.

Peter Mortensen's user avatar

answered Oct 22, 2012 at 13:09

Thomas E's user avatar

Thomas EThomas E

3,7982 gold badges20 silver badges13 bronze badges

0

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 Jan 4, 2018 at 17:08

rustyMagnet's user avatar

rustyMagnetrustyMagnet

3,3511 gold badge30 silver badges40 bronze badges

0

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.

See: git-restore doc for git 2.23.0

answered Sep 5, 2019 at 16:05

cb2's user avatar

cb2cb2

6699 silver badges15 bronze badges

1

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.

Peter Mortensen's user avatar

answered Nov 29, 2013 at 20:05

kzar's user avatar

kzarkzar

2,9512 gold badges17 silver badges13 bronze badges

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 Nov 29, 2012 at 16:35

J. Ceron's user avatar

J. CeronJ. Ceron

1,15410 silver badges8 bronze badges

2

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)

Peter Mortensen's user avatar

answered Jul 2, 2012 at 20:52

bonyiii's user avatar

bonyiiibonyiii

2,80329 silver badges25 bronze badges

Plus point: The below methods does work good for the scenario that files/folders got deleted even from your Trash or Recycle bin.

Files/Folders are deleted from working tree but not committed yet:

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

Files/Folders are deleted in some commit in the past:

  1. Use git log --diff-filter=D --summary to get details of the commits in which files/folder were deleted;
  2. Use 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. c7578994

answered May 30, 2021 at 16:18

Rishabh B's user avatar

Rishabh BRishabh B

4695 silver badges8 bronze badges

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 Dec 3, 2015 at 1:04

Tony Wickham's user avatar

Tony WickhamTony Wickham

4,6863 gold badges29 silver badges35 bronze badges

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.

Peter Mortensen's user avatar

answered Mar 6, 2020 at 9:59

Ritesh Adulkar's user avatar

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.

Jonathan Leffler's user avatar

answered Oct 26, 2018 at 6:41

Sudhanshu Jain's user avatar

Sudhanshu JainSudhanshu Jain

2,7811 gold badge8 silver badges4 bronze badges

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 Oct 6, 2021 at 16:13

Gerardo Suarez's user avatar

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.

Peter Mortensen's user avatar

answered May 9, 2019 at 18:19

Dave Baghdanov's user avatar

Dave BaghdanovDave Baghdanov

2,2785 gold badges24 silver badges35 bronze badges

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 Feb 12, 2020 at 18:56

Muhammad Soliman's user avatar

Muhammad SolimanMuhammad Soliman

21.1k5 gold badges109 silver badges74 bronze badges

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

Peter Mortensen's user avatar

answered Aug 2, 2019 at 15:42

Akbor's user avatar

AkborAkbor

1,2029 silver badges11 bronze badges

0

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 .

See Gif image
restore files by git

answered May 1, 2021 at 13:25

Eng_Farghly's user avatar

Eng_FarghlyEng_Farghly

1,8551 gold badge23 silver badges32 bronze badges

$ git log --diff-filter=D --summary  | grep "delete" | sort

answered Feb 5, 2018 at 1:01

kujiy's user avatar

kujiykujiy

5,7451 gold badge29 silver badges35 bronze badges

1

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.

Peter Mortensen's user avatar

answered Dec 2, 2019 at 12:58

Charles Duporge's user avatar

Charles DuporgeCharles Duporge

5922 gold badges11 silver badges30 bronze badges

It is possible, with help of Git copy file preserving history you need to copy the file before it was deleted.

I will write here a complete example. First I will prepare some test repository:

git init
echo "test content" > file.txt
git add file.txt
git commit -m "start"
echo "test content 2" >> file.txt
git commit -am "next commit"
rm file.txt
git commit -am "Delete file, lose history"

Now we have a test repository without the file. To restore the file with its commit history the process is following: create a branch where the file did exist. Then make two copies of this file, each with history. Then merge back to master and only one of the two copies will get deleted during the merge.
Be sure to use your commit hash instead of 190112b in example below.

git checkout 190112b -b before-deletion
git mv file.txt file1.txt
git commit -m "Move file (1)"
SAVED=`git rev-parse HEAD`
git reset --hard "HEAD^"
git mv file.txt file2.txt
git commit -m "Move file (2)"
git merge $SAVED
git commit -a -n

OK, so now in this branch we have two copies of this file. Each copy preserves history. Now when we merge this back into master, one file will disappear (or will have wrong history), the other one will keep the history.

git checkout master
git merge before-deletion
git commit -a -n
git rm file1.txt
git mv file2.txt file.txt
git commit -m "recovery finished"

And that’s it.

There are situations when you have deleted a file in the project, and now you want to get it back. Here, we suggest a solution to this issue. Follow the steps below and solve the problem.

Finding the file path

If you have deleted a file and do not know on which path it was, then you should execute the following command:

git log --all --full-history -- "*MyFile.*"

This command will display all the commits from the commit history that contain changes on the files, whose names match the given pattern. Hence, we can use the commit hashes found with the help the command above to get the file path by running the following command:

git show --pretty="" --name-only <sha1-commit-hash>

Displaying the specified version of the file

After finding out the file path, we can bring out the commits on which it was changed by running the command below:

git log --all --full-history -- <path-to-file>

Now we have the file path and the commits where it was changed, so we can find the version of the file, which we want to restore by running the command below:

git show <sha1-commit-hash> -- <path-to-file>

Restoring file into working copy

For restoring it into your working copy using the git checkout command:

git checkout <sha1-commit-hash>^ -- <path-to-file>

The caret symbol (^) gets the version of the file of the previous commit. At the moment of <sha1-commit-hash> commit, the file can be deleted, so you need to look at the previous commit to get the contents of the deleted file(s).

The git log command shows committed snapshots used for listing and filtering the project history and searching for particular changes. It is a tool used for examining a repository’s history and finding a particular version of a project. The --alloption shows all the commits in the history of branches, tags, and other references. The --full-history option simplifies the history explaining the final state of the tree.

The git checkout command is used for switching branches or restoring working tree files. It operates on files, commits, and branches. It allows switching between multiple features in just a single repository. The git checkout command works with the git branch command. It updates the files in the working directory to match the version stored in that branch, instructing Git to record all the new commits.

How to Recover a Deleted File in Git – Revert Changes After a Hard Reset

Git is a version control system that helps you keep track of the changes in a project’s life cycle. It preserves the history of the project and allows you and your team members to coordinate effectively throughout.

There could be situations where you deleted a file and you want to recover it. The good news is that you can – most of the time – recover the files when using a version control system (VCS).

In this tutorial, we will learn the different methods that Git offers to restore deleted files.

How to Recover Files after Committing Changes

Let’s say you committed a change but did a hard reset ( git reset --hard HEAD) to a different commit which removed the latest commit from your current branch.

Untitled-2022-06-21-2120

Hard reset explained.

In this case, you can restore the file using either git checkout or git reflog.

You can find the hash-ID of the previous commit from the command: git log.

After that, simply revert to the previous commit using:

git checkout <hash-id>

In case you don’t have the hash ID, you can use the command git reflog.

reflog is a logging mechanism and keeps a track of all the changes against their unique hash-id.

Below is an example of the output of git reflog:

image-155

Output of git reflog

Pick the commit ID and use it to revert to that commit.

git reflog <hash-id>

How to Recover Files When Changes Are Staged but Not Committed

Suppose you staged a file with git add <file-name> and then did a hard reset with git reset --hard HEAD before committing. Afterward, you found out that the staged file is missing. In this case, also, you can recover the files.

We can use the command git fsck to recover the files after a hard reset.

What is git fsck?

git fsck stands for file system check. It checks for all the “dangling blobs” in the .git directory that are not part of any changes. For example, there could be some changes that were staged but not added anywhere.

image-154

Output of git fsck.

Once we are able to identify the “dangling blobs”, we can view the details using git show.

git show f24facc98b387a375a50ba6d19193626cbfe7d45

Depending on the change, you’ll be able to view your respective changes.

You might also want to save the changes in a file. You can simply redirect the output to a file using the > operator.

git show f24facc98b387a375a50ba6d19193626cbfe7d45 > restored_file.txt

Now, restored_file.txt will include the contents of the commit.

How to Restore Changes that Are Neither Committed nor Staged

In the case where the changes are neither staged nor committed, Git can’t help you recover the files.

The reason is that the files weren’t added to staging and Git can not tell the status of those files.

In this case, it would be helpful to search in temp files or the cached history of your text editor.

Wrapping up

When working on risky files, it is always better to use a VCS. In this way, the files will be preserved and the chances of accidental data loss are reduced.

In this tutorial, we learned how to restore deleted files whether they are staged or committed.

I hope you found this tutorial helpful. Thank you for reading till the end.

What’s your favorite thing you learned from this tutorial? Let me know on Twitter!

You can also read my other posts here.



Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

Добавить комментарий