我們在本地修改文件、或者刪除文件後,如果想恢復這些文件內容爲git倉庫保存的版本,可以使用下面幾個命令:
-
git checkout [--] <filepath>
:可以恢復還沒有執行 git add 的文件,但不能恢復已經執行過 git add 的文件 -
git reset [--] <filepath>
:把文件從git的staged區域移除,即取消git add,再使用 git checkout 進行恢復 -
git reset --hard
:恢復整個git倉庫的文件內容爲當前分支的最新版本
git checkout [--] <filepath>
當修改文件內容、或者刪除本地文件後,如果還沒有執行 git add
命令添加改動,可以執行 git checkout [--] <filepath>
命令來把 filepath 指定的文件恢復成當前git分支的最新版本。對該命令的參數說明如下:
-
[--]
:表示--
是可選參數,該參數用於指定後面跟着的參數只是文件路徑,而不是branch分支名或者commit信息。
如果當前有一個branch分支名是 hello.c,且當前目錄下有一個 hello.c 文件,那麼不加--
參數時,git checkout hello.c
表示切換到 hello.c 分支,而不是覆蓋 hello.c 文件的改動。這種場景下,必須用git checkout -- hello.c
指定覆蓋 hello.c 文件的改動,--
參數可以消除歧義。
在沒有名稱歧義的情況下,可以不提供--
參數。例如使用git checkout hello.c
覆蓋 hello.c 文件。
-
<filepath>
:filepath 指定要被覆蓋的文件路徑,基於當前shell工作目錄進行尋址。例如要覆蓋當前目錄下 src 子目錄的 utils.c 文件,要寫爲 src/utils.c.
雖然filepath參數提供的文件路徑是基於當前shell工作目錄進行尋址,但這只是描述文件目錄結構關係,並不代表在當前工作目錄底下一定存在這個文件。例如刪除本地的 src/utils.c 文件後,可以用 git checkout src/utils.c
命令恢復這個文件,但是執行這個命令時,本地並不存在 src/utils.c 文件,執行之後纔會重新生成。
- 注意:這裏的
[]
表示是可選參數,<>
限定非命令選項的參數名,它們都不是參數自身的內容,在輸入的時候不要加[]
或者<>
。 - 在Bash shell下面,
.
表示當前目錄路徑。當不提供--
參數、filepath 參數寫爲.
時,git checkout .
命令表示覆蓋當前目錄及其子目錄的改動。這是 git checkout 命令常用的形式。
注意:當不帶有 --
參數時,在 bash shell 下使用 Tab 鍵補全,默認只會列出本地分支名、遠端分支名、和 git refs,不會列出本地文件名。即,默認無法用 Tab 鍵來補全文件名,即使當前目錄下只有一個文件也無法補全,可以先輸入文件名開頭的部分,才能用 Tab 鍵補全。
當帶有 --
參數時,在 bash shell 下使用 Tab 鍵補全,默認只會列出本地文件名,不會列出分支名和 git refs,方便補全本地文件名。
git reset
當修改文件內容、或者刪除本地文件後,如果已經執行過 git add 命令來添加該文件的改動,那麼用 git checkout 命令無法恢復這個文件爲當前git分支的最新版本,需要使用下面的 git reset 命令進行處理:
-
git reset [--] <filepath>
:把 filepath 文件從git的staged區域移除,相當於還沒有執行 git add 命令。該命令不會恢復文件內容,需要再使用上面描述的 git checkout 命令來恢復文件。
當使用已刪除的文件路徑作爲參數時,git checkout 命令可以不加--
參數,但是 git reset 不加--
參數會報錯,必須使用--
來表示後面跟着的是文件路徑。例如 hello.c 文件被刪除,git checkout hello.c 可以正常恢復該文件,而 git reset hello.c 會報錯,git reset -- hello.c 不會報錯。
-
git reset --hard
:將整個git倉庫的文件都恢復成當前分支的最新版本,會直接恢復文件內容,不需要再執行 git checkout 命令。
該命令不需要傳入任何文件路徑,默認對git倉庫跟蹤的工作目錄、所有子目錄、以及所有文件都生效。例如,當前shell的工作目錄位於某個子目錄下,要恢復其父目錄下的改動,不需要先執行 cd 命令切換到父目錄,直接在子目錄下執行 git reset --hard
命令就能恢復父目錄下的改動。