簡體   English   中英

如何在 Git 存儲庫中查找和恢復已刪除的文件?

[英]How do I find and restore a deleted file in a Git repository?

假設我在 Git 存儲庫中。 我刪除一個文件並提交該更改。 我繼續工作並做出更多的承諾。 然后,我發現我需要在刪除該文件后恢復它。

我知道我可以使用git checkout <commit> -- filename.txt簽出文件,但我不知道該文件何時被刪除。

  1. 如何找到刪除給定文件名的提交?
  2. 如何將該文件恢復到我的工作副本中?

查找影響給定路徑的最后一個提交。 由於該文件不在 HEAD 提交中,因此之前的提交必須已將其刪除。

git rev-list -n 1 HEAD -- <file_path>

然后在提交之前簽出版本,使用插入符號 ( ^ ) 符號:

git checkout <deleting_commit>^ -- <file_path>

或者在一個命令中,如果$file是有問題的文件。

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

如果您使用 zsh 並啟用了 EXTENDED_GLOB 選項,則插入符號將不起作用。 您可以使用~1代替。

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"
  1. 使用git log --diff-filter=D --summary獲取所有已刪除文件和已刪除文件的提交;
  2. 使用git checkout $commit~1 path/to/file.ext恢復被刪除的文件。

其中$commit是您在步驟 1 中找到的提交的值,例如e4cf499627

要恢復文件夾中所有已刪除的文件,請輸入以下命令。

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

我來這個問題是為了恢復我剛剛刪除但尚未提交更改的文件。 萬一您發現自己處於這種情況,您需要做的就是以下幾點:

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

如果你瘋了,請使用git-bisect 這是做什么:

git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>

現在是時候運行自動化測試了。 如果foo.bar存在,shell 命令'[ -e foo.bar ]'將返回 0,否則返回 1。 git-bisect的“運行”命令將使用二進制搜索來自動找到測試失敗的第一個提交。 它從給定范圍(從好到壞)的中間開始,並根據指定測試的結果將其減半。

git bisect run '[ -e foo.bar ]'

現在你在提交刪除它。 從這里,您可以跳回未來並使用git-revert撤消更改,

git bisect reset
git revert <the offending commit>

或者您可以返回一次提交並手動檢查損壞情況:

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .

我最喜歡的新別名,基於bonyiii回答(贊成),以及我自己關於“將參數傳遞給 Git 別名命令”的回答:

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'

我丟失了一個文件,在幾次提交前被錯誤刪除?
快的:

git restore my_deleted_file

危機化解了。

警告,隨着 Git 2.23(2019 年第三季度)的推出,實驗性命令git restore (!)。
所以重命名這個別名(如下圖)。


Robert Dailey 在評論中提出以下別名:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

jegan 在評論中補充道:

為了從命令行設置別名,我使用了這個命令:

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\"" 

如果您知道文件名,這是使用基本命令的簡單方法:

列出該文件的所有提交。

git log -- path/to/file

最后一次提交(最頂層)是刪除文件的那個。 所以你需要恢復倒數第二個提交。

git checkout {second to last commit} -- path/to/file

要恢復已刪除和提交的文件:

git reset HEAD some/path
git checkout -- some/path

它在 Git 版本 1.7.5.4 上進行了測試。

我有這個解決方案

  1. 使用以下方法之一獲取文件被刪除的提交的 id。

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word* git log --stat | grep --context=5 *word* # 如果您幾乎不記得任何內容,推薦使用
  2. 你應該得到類似的東西:

提交 bfe68bd117e1091c96d2976c99b3bcc8310bebe7 作者:Alexander Orlov 日期:2011 年 5 月 12 日星期四 23:44:27 +0200

 replaced deprecated GWT class - gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script

提交 3ea4e3af253ac6fd1691ff6bb89c964f54802302 作者:Alexander Orlov 日期:2011 年 5 月 12 日星期四 22:10:22 +0200

3 . 現在使用提交 ID bfe68bd117e1091c96d2976c99b3bcc8310bebe7 執行以下操作:

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

由於提交 id 引用了文件已被刪除的提交,您需要在 bfe68b 之前引用提交,您可以通過附加^1來完成。 這意味着:在 bfe68b 之前給我提交。

如果您只進行了更改並刪除了一個文件,但沒有提交它,現在您與您的更改分手了

git checkout -- .

但是您刪除的文件沒有返回,您只需執行以下命令:

git checkout <file_path>

很快,你的文件又回來了。

實際上,這個問題直接與 Git 有關,但像我這樣的人使用WebStorm VCS等 GUI 工具,而不是了解 Git CLI 命令。

我右鍵單擊包含已刪除文件的路徑,然后轉到 Git,然后單擊Show History

在此處輸入圖像描述

VCS 工具顯示了所有修訂序列,我可以看到每個修訂的所有提交和更改。

在此處輸入圖像描述

然后我選擇我的朋友刪除PostAd.js文件的提交。 現在見下圖:

在此處輸入圖像描述

現在,我可以看到我想要刪除的文件了。 我只需雙擊文件名即可恢復。

在此處輸入圖像描述

我知道我的答案不是 Git 命令,但對於初學者和專業開發人員來說,它快速、可靠且容易。 WebStorm VCS 工具非常棒,非常適合與 Git 一起使用,它不需要任何其他插件或工具。

git checkout /path/to/deleted.file

git undelete path/to/file.ext

  1. 將其放入您的.bash_profile (或打開命令外殼時加載的其他相關文件):

     git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
  2. 然后使用:

     git undelete path/to/file.ext

此別名首先檢查以查找該文件存在的最后一次提交,然后從該文件存在的最后一次提交中對該文件路徑進行 Git 簽出。 來源

在許多情況下,將coreutils (grep、sed 等)與 Git 結合使用會很有用。 我已經非常了解這些工具,但 Git 不太了解。 如果我想搜索已刪除的文件,我會執行以下操作:

git log --raw | grep -B 30 $'D\t.*deleted_file.c'

當我找到修訂/提交時:

git checkout <rev>^ -- path/to/refound/deleted_file.c

就像其他人在我之前所說的那樣。

該文件現在將恢復到刪除之前的狀態。 如果您想保留它,請記住將其重新提交到工作樹。

我必須從特定提交中恢復一堆已刪除的文件,並使用兩個命令對其進行管理:

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 

(注意每個命令末尾的尾隨空格。)

這些文件已添加到 .gitignore 文件中,然后使用git rm清除。 我需要恢復文件,然后取消暫存它們。 我有數百個文件要恢復,並且像在其他示例中那樣為每個文件手動輸入內容會太慢。

我有同樣的問題。 在不知不覺中,我創建了一個懸空提交

列出懸空提交

git fsck --lost-found

檢查每個懸空提交

git reset --hard <commit id>

當我移動到懸空提交時,我的文件重新出現。

git status的原因:

“HEAD detached from <commit id where it detached>”

找到刪除文件的提交:

git log --diff-filter=D --oneline -- path/to/file | cut -f -d ' '

樣本輸出:

4711174

從 Git 2.23 開始,實際上有一個restore命令。 仍處於試驗階段,但為了恢復您在提交中刪除的內容(在本例中為 4711174),您可以輸入:

git restore --source=4711174^ path/to/file

請注意提交 id 之后的^ ,因為我們想從刪除文件之前的提交中恢復某些內容。

--source參數告訴restore命令在哪里尋找要恢復的文件,它可以是任何提交,甚至是索引。

請參閱: git 2.23.0 的 git-restore 文檔

在我們的案例中,我們不小心刪除了提交中的文件,后來一些提交我們意識到我們的錯誤,並希望取回所有被刪除的文件,而不是那些被修改的文件。

根據查爾斯·貝利的出色回答,這是我的單線:

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)
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

恢復已刪除的文件:

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

如果您知道刪除文件的提交,請運行以下命令,其中<SHA1_deletion>是刪除文件的提交:

git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --

管道前面的部分列出了提交中刪除的所有文件; 它們都是從以前的提交中簽出以恢復它們。

要獲得最好的方法,請嘗試一下。


首先,找到刪除文件的提交的提交 ID。 它將為您提供刪除文件的提交摘要。

git log --diff-filter=D --summary

git checkout 84sdhfddbdddf~1

注意: 84sdhfddbddd是您的commit id

通過這個,您可以輕松恢復所有已刪除的文件。

加分點:以下方法確實適用於文件/文件夾甚至從您的垃圾箱或回收站中被刪除的情況。

文件/文件夾已從工作樹中刪除但尚未提交:

I. 如果您還沒有索引(git add)您的更改,您可以恢復目錄的內容:

git restore -- path/to/folder_OR_file

二、 如果刪除已編入索引,則應首先重置:

git reset -- path/to/folder_OR_file

然后執行, git restore path/to/folder_OR_file

文件/文件夾在過去的某些提交中被刪除:

  1. 使用git log --diff-filter=D --summary獲取刪除文件/文件夾的提交的詳細信息;
  2. 使用git checkout $commit~1 path/to/folder_OR_file恢復已刪除的文件/文件夾。 其中$commit是您在步驟 1 中找到的提交的 sha 值,例如 c7578994

簡單而精確——

首先,通過以下方式獲取最新的穩定提交,其中包含該文件 -

git log 

假設你找到 $commitid 1234567...,那么

git checkout <$commitid> $fileName

這將恢復該提交中的文件版本。

你總是可以git revert刪除文件的提交。 這假設刪除是提交中的唯一更改。

> git log
commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3
Author: Dave <dave@domain.com>
Date:   Thu May 9 11:11:06 2019 -0700

    deleted readme.md

如果您繼續工作,並且后來意識到您不想提交刪除提交,您可以使用以下方法恢復它:

> git revert 2994bd

現在git log顯示:

> git log
Author: Dave <dave@domain.com>
Date:   Thu May 9 11:17:41 2019 -0700

    Revert "deleted readme"

    This reverts commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3.

並且readme.md已恢復到存儲庫中。

如果您只想在 master 中恢復相同的文件,這是我找到的最簡單的解決方案:

git checkout master -- path/to/File.java

我也有這個問題,使用下面的代碼將以前的文件檢索到本地目錄:

git checkout <file path with name>

下面的例子對我有用:

git checkout resources/views/usaSchools.blade.php

如果尚未提交刪除,則以下命令將恢復工作樹中已刪除的文件。

$ git checkout -- <file>

您可以使用以下命令獲取工作樹中所有已刪除文件的列表。

$ git ls-files --deleted

如果已提交刪除,則找到它發生的提交,然后從該提交中恢復文件。

$ git rev-list -n 1 HEAD -- <file>
$ git checkout <commit>^ -- <file>

如果您正在尋找要恢復的文件的路徑,以下命令將顯示所有已刪除文件的摘要。

$ git log --diff-filter=D --summary

您可以簽出已刪除的文件:

git checkout

輸出

D       index.html

要恢復它:

git restore index.html

如果您刪除了多個文件並且需要恢復所有使用:

git restore .

見 Gif 圖像通過 git 恢復文件

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

為了使用 Git 恢復所有已刪除的文件,您還可以執行以下操作:

git checkout $(git ls-files --deleted)

其中git ls-files --deleted列出所有已刪除的文件, git checkout $(git command)恢復參數中的文件列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM