模擬面試官:Git 如何進行撤銷操做?

在 Git 中,有三個命令能夠用來撤銷操做,分別是 git resetgit revertgit checkoutgit

背景知識

Git 倉庫由三個部分組成,工做區、暫存區和 Commit 歷史。安全

咱們在工做區進行開發,而後經過 git add 將文件修改添加到暫存區,而後 git commit 提交更改,就把暫存區的全部內容提交到了當前分支的 Commit 歷史中去了。bash

git revert

該操做只能做用於 Commit,而不能做用於文件。同時,該操做會建立一個新的 Commit 來撤銷以前提交的更改,它不會去修改現有的歷史記錄。spa

換句話說,這個命令是安全的,它不會丟失 Commit 記錄,只會新增。code

git reset

這個命令相對來講就要複雜一點了,它可以同時做用於 Commit 和文件,用來撤銷尚未提交到遠程倉庫的改動。cdn

對於 Commit 來講,git reset 會移動 HEAD 的位置,而且還能夠變動暫存區和工做區,該操做有三個選項:blog

  1. --soft:該選項會修改 HEAD 位置,而工做區和暫存區不會有變化
  2. --mixed:默認選項,會修改 HEAD 位置以及暫存區,而工做區不會有變化
  3. --hard:修改 HEAD 位置,暫存區和工做區都會被更新到指定 Commit 的狀態

是否是有點繞,不要緊咱們實戰說話:開發

touch a
git add a
git commit 'feat: 添加 a 文件'
touch b
git add b
git commit 'feat: 添加 b 文件'
touch c
git add c
git commit 'feat: 添加 c 文件'
複製代碼

如今,咱們使用 git log 能夠看到有三條 commit 記錄,使用 git status 能夠看到暫存區的狀態爲空。string

接下來,咱們使用 git reset HEAD~1 命令,而後咱們再次使用 git loggit status 命令,能夠看到 Commit 歷史中,HEAD 的位置已經修改到了提交 b 的位置,同時在工做目錄中咱們還能找到 c 文件,而且 c 文件被移出了暫存區,這就是 mixedit

接下來,咱們再次將 c 文件提交回去恢復成初始狀態,此次咱們在命令後加上 --soft,咱們再來看,HEAD 的位置依然被修改了,而且工做區 c 文件依然存在,不一樣的是 c 依然在暫存區中。

最後咱們加上 --hard 再來看一看,咱們能夠發現,HEAD 變了,暫存區和工做區的 c 文件都被移除了,這個參數比較危險,也就不建議你們在公共分支上進行操做了。

說完了 Commit,那文件是如何撤銷的呢?對於文件來講,上面提到的三個參數是不起做用的,它會去更新暫存區的對應文件到指定 Commit 的時候的版本。

仍是上面的例子,若是我使用命令 git reset HEAD~1 c,會出現什麼結果呢?你們能夠想想,答案是,它會將 c 文件更新到上一個 Commit 的時候的版本,也就是尚未被建立的狀態,因此你執行 git status 能夠發現暫存區中存在 delete: c,這就是文件的撤銷。

git checkout

當你 checkout Commit 的時候,會將 HEAD 指向你指定的 Commit,而且這個沒有分支指向這個 HEAD,因此 checkout 以後,會處於一個 detached HEAD 的分支,若是你要提交 Commit 到這個分支,你應該先 checkout 一個分支出來,而後再進行提交。

當你 checkout 文件的時候,checkout 命令和 reset 就有點相似,可是它不會更新暫存區,只會更新工做區,當你使用 git checkout <commit> <filename> 的時候,就會把工做區的對應文件更新到指定 Commit 版本的狀態,當你使用 git checkout -- <filename> 的時候就會撤銷掉在工做區這個文件的修改。

對於這些操做,你們必定要注意,不要亂用,把倉庫搞亂了就很差了。

很是感謝您的閱讀,歡迎關注、轉發、分享支持我。

相關文章
相關標籤/搜索