Jump to content

Restoring deleted files in Git in Mandarin: Difference between revisions

From LemonWiki共筆
Created page with "= 復原 GIT 誤刪除的檔案 = {{LanguageSwitcher | content = EN, 漢字 }} == 復原方法 == === 方法一:透過 Fork 右鍵選單 === 使用 [https://git-fork.com/ Fork Git 客戶端軟體],並且對 <code>Deleted.file</code> 右鍵選擇了 '''Reset File to'''。 # 右鍵點擊被刪除的檔案 # 選擇 '''Reset File to''' → <code>State at Commit...</code> 或 <code>..."
Tag: wikieditor
 
mNo edit summary
 
Line 1: Line 1:
= 復原 GIT 誤刪除的檔案 =
= 復原 Git 誤刪除的檔案 =


{{LanguageSwitcher | content = [[Restoring deleted files in Git | EN]], [[Restoring deleted files in Git in Mandarin | 漢字]] }}
{{LanguageSwitcher | content = [[Restoring deleted files in Git | EN]], [[Restoring deleted files in Git in Mandarin | 漢字]] }}
Line 7: Line 7:
=== 方法一:透過 Fork 右鍵選單 ===
=== 方法一:透過 Fork 右鍵選單 ===


使用 [https://git-fork.com/ Fork Git 客戶端軟體],並且對 <code>Deleted.file</code> 右鍵選擇了 '''Reset File to'''。
使用 [https://git-fork.com/ Fork Git 客戶端軟體],在歷史紀錄中找到刪除檔案的 commit。


# 右鍵點擊被刪除的檔案
# 右鍵點擊被刪除的檔案 <code>Deleted.file</code>。
# 選擇 '''Reset File to''' → <code>State at Commit...</code> 或 <code>State Before Commit...</code>
# 選擇 '''Reset File to''',再依手上的 commit 選擇下列項目。
#* <code>State at Commit...</code> → 還原到某個特定 commit 的狀態
#* <code>State at Commit...</code>:還原到指定 commit 中的檔案版本。選擇檔案仍存在的 commit。
#* <code>State Before Commit...</code> → 還原到該 commit 之前的狀態
#* <code>State Before Commit...</code>:還原到指定 commit 之前的狀態。如果選到的是刪除檔案的 commit,可用此選項取回刪除前的版本。


> '''建議:''' 直接用選單,點 <code>State Before Commit...</code> 即可快速還原到刪除前的狀態。
=== 方法二:使用命令列 ===


=== 方法二:命令列 ===
請從 Git 專案根目錄執行。檔案路徑的大小寫與目錄層級須和來源 commit 裡的路徑一致。若同一路徑已有未提交的修改,請先備份,因為還原會覆蓋該檔案。


> '''注意:''' 檔案路徑需要完全一樣(大小寫、目錄層級都要一致)。
==== 檔案仍存在於目前的 HEAD ====
 
如果檔案是在本機刪除,且目前的 <code>HEAD</code> 仍有這個檔案,可以直接從 <code>HEAD</code> 取回:
 
<pre lang="bash">
git restore --source=HEAD -- 'sub_folder/Deleted.file'
</pre>
 
==== 已知檔案仍存在的 commit ====
 
把 <code>&lt;commit_hash&gt;</code> 換成檔案仍存在時的 commit hash。例如,若手上的 commit 是新增這個檔案的那一筆,就直接使用該筆 commit:


1. 從最新 commit 還原
<pre lang="bash">
<pre lang="bash">
git checkout HEAD -- sub_folder/Deleted.file
git restore --source='<commit_hash>' -- 'sub_folder/Deleted.file'
</pre>
</pre>


2. 或從特定 commit 還原(用 commit hash)
==== 只知道刪除檔案的 commit ====
 
一般只有一個父提交的情況下,在刪除檔案的 commit hash 後加上 <code>^</code>,即可從刪除前的版本取回檔案:
 
<pre lang="bash">
<pre lang="bash">
git checkout <commit_hash> -- sub_folder/Deleted.file
git restore --source='<commit_hash>^' -- 'sub_folder/Deleted.file'
</pre>
</pre>


=== 方法三:從 Local Changes 還原 ===
如果刪除發生在合併提交,<code>^</code> 指第一個父提交。請先確認要取回的版本在哪一個父提交。
 
==== 確認結果並視需要加入暫存區 ====


如果檔案還在 '''Local Changes''' 裡顯示為已刪除:
上述 <code>git restore --source</code> 指令會寫回工作目錄。先確認檔案內容與 Git 狀態:


# 點左側 '''Local Changes'''
<pre lang="bash">
# 找到該檔案
git status --short -- 'sub_folder/Deleted.file'
# 右鍵 → '''Discard Changes'''
</pre>


== 常見問題 ==
如果要把復原的檔案納入下一次提交,再將它加入暫存區:
 
<pre lang="bash">
git add -- 'sub_folder/Deleted.file'
</pre>


=== 很久前刪除的檔案,無法從 Fork 快速找到刪除檔案的哪一筆紀錄 commit hash ===
==== 使用較舊版本的 Git ====


如果還記得檔案名稱(大小寫要一致,但不清楚放在哪一個目錄):
如果 Git 版本尚未提供 <code>git restore</code>,可以用 <code>git checkout</code> 指定來源與檔案路徑。這種寫法會同時更新工作目錄和暫存區:


<pre lang="bash">
<pre lang="bash">
git log --all --full-history -- "**/Deleted.file"
git checkout HEAD -- 'sub_folder/Deleted.file'
git checkout '<commit_hash>' -- 'sub_folder/Deleted.file'
</pre>
</pre>


<code>**</code> 與 <code>*</code> 符號說明:
依來源擇一執行。第二行的 <code>&lt;commit_hash&gt;</code> 要換成檔案仍存在時的 commit hash。
# <code>**</code> 匹配任意層數目錄(包含零層)
 
# <code>*</code> 只匹配單一層目錄或檔名中的任意字元
=== 方法三:從 Local Changes 還原 ===
 
如果檔案還在 Fork 的 '''Local Changes''' 裡顯示為已刪除:
 
# 點左側的 '''Local Changes'''。
# 找到被刪除的檔案。
# 右鍵選擇 '''Discard Changes'''。
 
== 常見問題 ==


不確定路徑深度時建議用 <code>**</code>。
=== 很久以前刪除的檔案,要怎麼找到 commit? ===


如果不確定檔名大小寫,用 <code>grep -i</code> 做大小寫不敏感的搜尋:
如果記得檔名,但忘了目錄,可以搜尋各個本機可見分支與其他 Git 參照的歷史,並列出符合的提交和路徑:


<pre lang="bash">
<pre lang="bash">
git log --all --full-history --name-only --format="" | grep -i "deleted.file"
git -c core.quotePath=false log --all --full-history --name-status -- ':(glob)**/Deleted.file'
</pre>
</pre>


出現 N 次,代表這個檔案在 GIT 歷史中被修改過 N 次,有很多版本可以還原。找到正確路徑後,再用完整正確路徑去還原。
<code>:(glob)</code> 啟用 glob 路徑比對。<code>**/</code> 可匹配零層或多層目錄,<code>*</code> 可匹配單一路徑元件中的字元。


找到要復原的 commit hash:
如果不確定檔名大小寫,可以加上 <code>icase</code>:


<pre lang="bash">
<pre lang="bash">
git log --all --full-history -- "**/Deleted.file"
git -c core.quotePath=false log --all --full-history --name-status -- ':(glob,icase)**/deleted.file'
</pre>
</pre>


=== 為什麼 <code>git show HEAD --name-only | grep Deleted.file</code> 沒有結果? ===
結果中的 <code>A</code> 表示新增,<code>M</code> 表示修改,<code>D</code> 表示刪除。找到所需版本後,用結果中顯示的完整路徑還原。若選到的是刪除紀錄,請依「只知道刪除檔案的 commit」的方式操作。


<code>git show HEAD --name-only</code> 只會列出'''最新那一筆 commit 有變動的檔案''',不是所有檔案,所以沒出現不代表不存在。
=== 為什麼 <code>git show HEAD --name-only</code> 找不到檔案? ===


可能原因:
<code>git show HEAD --name-only</code> 顯示的是 <code>HEAD</code> 那筆提交的變動清單。檔案可能仍存在於 <code>HEAD</code>,只是這筆提交沒有修改它。
* 這個檔案很久沒被修改,最近的 commit 根本沒動到它
* 檔案已經被刪除了
* 路徑不對


=== 先確認檔案存在位置 ===
=== 如何確認檔案目前在哪裡? ===


看它現在存不存在於 working tree:
檢查工作目錄中是否有這個檔案:


<pre lang="bash">
<pre lang="bash">
find . -name "Deleted.file"
find . -type f -name 'Deleted.file'
</pre>
</pre>


看目前 HEAD 裡有沒有這個檔案(不管有沒有被修改):
檢查目前的 <code>HEAD</code> 快照是否包含這個路徑:


<pre lang="bash">
<pre lang="bash">
git ls-files | grep Deleted.file
git -c core.quotePath=false ls-tree -r --name-only HEAD -- 'sub_folder/Deleted.file'
</pre>
</pre>
也可以把 <code>HEAD</code> 換成想檢查的 commit hash。
=== 為什麼中文檔名顯示成反斜線和數字? ===
Git 可能會將中文路徑顯示為跳脫字元。可以對單次指令設定 <code>core.quotePath=false</code>,用來確認實際檔名:
<pre lang="bash">
git --no-pager -c core.quotePath=false show --name-only --format= '<commit_hash>'
</pre>
執行還原時,請使用實際檔名。若要查看某個路徑是否存在於該 commit 的快照,可以使用上一節的 <code>git ls-tree</code>。


== 參考資料 ==
== 參考資料 ==
Line 95: Line 131:
* [https://git-scm.com/docs/git-restore Git 官方文件 - git-restore]
* [https://git-scm.com/docs/git-restore Git 官方文件 - git-restore]
* [https://git-scm.com/docs/git-log Git 官方文件 - git-log]
* [https://git-scm.com/docs/git-log Git 官方文件 - git-log]
* [https://git-scm.com/docs/git-ls-tree Git 官方文件 - git-ls-tree]
* [https://www.git-tower.com/learn/git/faq/restoring-deleted-files How to Restore a Deleted File in Git - git-tower]
* [https://www.git-tower.com/learn/git/faq/restoring-deleted-files How to Restore a Deleted File in Git - git-tower]
* [https://rewind.com/blog/recovering-deleted-files-in-github/ Recovering Deleted Files in GitHub - Rewind]
* [https://rewind.com/blog/recovering-deleted-files-in-github/ Recovering Deleted Files in GitHub - Rewind]
Line 100: Line 137:
* [https://www.atlassian.com/git/tutorials/git-log Advanced Git Log - Atlassian]
* [https://www.atlassian.com/git/tutorials/git-log Advanced Git Log - Atlassian]
* [https://github.blog/open-source/git/gits-database-internals-iii-file-history-queries/ Git's database internals III: file history queries - GitHub Blog]
* [https://github.blog/open-source/git/gits-database-internals-iii-file-history-queries/ Git's database internals III: file history queries - GitHub Blog]


[[Category: Git]]
[[Category: Git]]
[[Category: Revised with LLMs]]
[[Category: Revised with LLMs]]

Latest revision as of 16:00, 10 November 2026

復原 Git 誤刪除的檔案[edit]

🌐 Switch language: EN, 漢字


復原方法[edit]

方法一:透過 Fork 右鍵選單[edit]

使用 Fork Git 客戶端軟體,在歷史紀錄中找到刪除檔案的 commit。

  1. 右鍵點擊被刪除的檔案 Deleted.file。
  2. 選擇 Reset File to,再依手上的 commit 選擇下列項目。
    • State at Commit...:還原到指定 commit 中的檔案版本。選擇檔案仍存在的 commit。
    • State Before Commit...:還原到指定 commit 之前的狀態。如果選到的是刪除檔案的 commit,可用此選項取回刪除前的版本。

方法二:使用命令列[edit]

請從 Git 專案根目錄執行。檔案路徑的大小寫與目錄層級須和來源 commit 裡的路徑一致。若同一路徑已有未提交的修改,請先備份,因為還原會覆蓋該檔案。

檔案仍存在於目前的 HEAD[edit]

如果檔案是在本機刪除,且目前的 HEAD 仍有這個檔案,可以直接從 HEAD 取回:

git restore --source=HEAD -- 'sub_folder/Deleted.file'

已知檔案仍存在的 commit[edit]

把 <commit_hash> 換成檔案仍存在時的 commit hash。例如,若手上的 commit 是新增這個檔案的那一筆,就直接使用該筆 commit:

git restore --source='<commit_hash>' -- 'sub_folder/Deleted.file'

只知道刪除檔案的 commit[edit]

一般只有一個父提交的情況下,在刪除檔案的 commit hash 後加上 ^,即可從刪除前的版本取回檔案:

git restore --source='<commit_hash>^' -- 'sub_folder/Deleted.file'

如果刪除發生在合併提交,^ 指第一個父提交。請先確認要取回的版本在哪一個父提交。

確認結果並視需要加入暫存區[edit]

上述 git restore --source 指令會寫回工作目錄。先確認檔案內容與 Git 狀態:

git status --short -- 'sub_folder/Deleted.file'

如果要把復原的檔案納入下一次提交,再將它加入暫存區:

git add -- 'sub_folder/Deleted.file'

使用較舊版本的 Git[edit]

如果 Git 版本尚未提供 git restore,可以用 git checkout 指定來源與檔案路徑。這種寫法會同時更新工作目錄和暫存區:

git checkout HEAD -- 'sub_folder/Deleted.file'
git checkout '<commit_hash>' -- 'sub_folder/Deleted.file'

依來源擇一執行。第二行的 <commit_hash> 要換成檔案仍存在時的 commit hash。

方法三:從 Local Changes 還原[edit]

如果檔案還在 Fork 的 Local Changes 裡顯示為已刪除:

  1. 點左側的 Local Changes。
  2. 找到被刪除的檔案。
  3. 右鍵選擇 Discard Changes。

常見問題[edit]

很久以前刪除的檔案,要怎麼找到 commit?[edit]

如果記得檔名,但忘了目錄,可以搜尋各個本機可見分支與其他 Git 參照的歷史,並列出符合的提交和路徑:

git -c core.quotePath=false log --all --full-history --name-status -- ':(glob)**/Deleted.file'

:(glob) 啟用 glob 路徑比對。**/ 可匹配零層或多層目錄,* 可匹配單一路徑元件中的字元。

如果不確定檔名大小寫,可以加上 icase:

git -c core.quotePath=false log --all --full-history --name-status -- ':(glob,icase)**/deleted.file'

結果中的 A 表示新增,M 表示修改,D 表示刪除。找到所需版本後,用結果中顯示的完整路徑還原。若選到的是刪除紀錄,請依「只知道刪除檔案的 commit」的方式操作。

為什麼 git show HEAD --name-only 找不到檔案?[edit]

git show HEAD --name-only 顯示的是 HEAD 那筆提交的變動清單。檔案可能仍存在於 HEAD,只是這筆提交沒有修改它。

如何確認檔案目前在哪裡?[edit]

檢查工作目錄中是否有這個檔案:

find . -type f -name 'Deleted.file'

檢查目前的 HEAD 快照是否包含這個路徑:

git -c core.quotePath=false ls-tree -r --name-only HEAD -- 'sub_folder/Deleted.file'

也可以把 HEAD 換成想檢查的 commit hash。

為什麼中文檔名顯示成反斜線和數字?[edit]

Git 可能會將中文路徑顯示為跳脫字元。可以對單次指令設定 core.quotePath=false,用來確認實際檔名:

git --no-pager -c core.quotePath=false show --name-only --format= '<commit_hash>'

執行還原時,請使用實際檔名。若要查看某個路徑是否存在於該 commit 的快照,可以使用上一節的 git ls-tree。

參考資料[edit]