
在 git 中撤消提交的最簡單方法是使用 revert 選項:
這會撤銷最近的提交。
包括使用 revert 在內,有兩種方法可以撤銷提交操作:
- git revert: 恢復 git 倉庫的先前狀態(tài),并將更改反映在 git 日志中;
- git reset:刪除上次提交。
還原提交(revert)
如果只是想要撤銷一個提交,但是不刪除 git 日志,可以使用 git revert 命令。其語法為我們剛剛提到過的:
上述命令中的 可以是用于提交的任何名稱,比如可以是在提交的 SHA1(提交時會得到這個值)、標記、引用名稱或者其他任何唯一標識提交的東西。
我們來舉個例子。首先在 git 中初始化一個文件:
$ git commit -m "init commit"
[master (root-commit) b1adf72] init commit
1 file changed, 3 insertions(+)
create mode 100644 ??README.md??
$ echo "a new line in readme" >> ??README.md??
使用 cat 命令來看一下這個文件的內容:
$ cat ??README.md??
Heading
A readme is useless if it is empty. But this readme is even more useless because it wastes the reader's time.
a new line in readme
然后我使用 git add . 將其添加到暫存區(qū),再然后做一次提交(提交的文本為:a commit that will live on for ever):
$ git commit -m 'a commit that will live on for ever'
[master b731901] a commit that will live on for ever
1 file changed, 1 insertion(+)
這次提交,系統(tǒng)返回給我一個唯一標識(master b731901)。現在我們運行 git revert 并使用該唯一標識,來恢復到上一次提交的狀態(tài):
$ git revert master b731901
[master 01c9be7] Revert "a commit that will live on for ever"
1 file changed, 1 deletion(-)
然后我們來看一下 git 日志,檢查撤銷操作有沒有反映在日志中:
$ git log
commit 01c9be75eff7b5ae48c6c35bbb7c63ac1ebc3fcd (HEAD -> master)
Author: Pratham Patel <??pratham@itsfoss.com??>
Date: Mon Feb 28 21:29:36 2022 +0530
$ git log
commit 01c9be75eff7b5ae48c6c35bbb7c63ac1ebc3fcd (HEAD -> master)
Author: Pratham Patel <??pratham@itsfoss.com??>
Date: Mon Feb 28 21:29:36 2022 +0530
Revert "a commit that will live on for ever"
This reverts commit b731901deaa30851832c07b7cb7ed535b68d473d.
commit b731901deaa30851832c07b7cb7ed535b68d473d
Author: Pratham Patel <??pratham@itsfoss.com??>
Date: Mon Feb 28 21:29:12 2022 +0530
a commit that will live on for ever
commit b1adf72e535921ff966ff78f062943b717e78a08
Author: Pratham Patel <??pratham@itsfoss.com??>
Date: Mon Feb 28 21:20:43 2022 +0530
init commit
上述輸出可以看出,git 日志記錄了這次撤銷,但是 README 文件已經被回復到先前的狀態(tài):
$ cat ??README.md??
Heading
A readme is useless if it is empty. But this readme is even more useless because it wastes the reader's time.
刪除提交
如果想要徹底恢復錯誤的提交且不保留日志,可使用 git reset。
git 中的每次提交(commit) 都相當于是倉庫的一個快照,另外,在 git 中有一個名為 HEAD 的引用變量--使用 git log 查看日志的時候就能看到。這個 HEAD 用于指向你正在工作的分支中的最近提交。
為了演示,我們首先更改一個文件:
$ git commit -m "init commit"
[master (root-commit) b1adf72] init commit
1 file changed, 3 insertions(+)
create mode 100644 ??README.md??
$ echo "a new line in readme" >> ??README.md??
$ cat ??README.md??
Heading
A readme is useless if it is empty. But this readme is even more useless because it wastes the reader's time.
a new line in readme
然后提交:
$ git add .
$ git commit -m "a commit that i will regret later on"
[master fb58caf] a commit that i will regret later on
1 file changed, 1 insertion(+)
然后使用 git reset 命令來撤銷這次提交:
$ git reset --soft HEAD~1
接下來看下 git 日志:
$ git log
commit b1adf72e535921ff966ff78f062943b717e78a08 (HEAD -> master)
Author: Pratham Patel <??pratham@itsfoss.com??>
Date: Mon Feb 28 21:20:43 2022 +0530
可以看到,我們的上次提交(提交文本 a commit that I will regret later on)已經不見了。
由此可見,這個提交被完全被刪除了,因為我將 HEAD 指向移動到了最后一個引用(用HEAD~1表示)。
這個刪除操作并沒有影響到我們的工作文件 ??README.md??:
$ git status
On branch master
Changes to be committed:
(use "git restore --staged ..." to unstage)
modified: ??README.md??
--soft 標志表示在運行 git reset 的時候修改的是 git 保存的日志。
如果想要將 git 存儲庫中的內容恢復到先前的狀態(tài),可使用 --hard 標志(不過要謹慎使用,確保需要的文件做好備份)。