在 Git 中,有三個命令能夠用來撤銷操做,分別是 git reset
、git revert
、git checkout
。git
Git 倉庫由三個部分組成,工做區、暫存區和 Commit 歷史。安全
咱們在工做區進行開發,而後經過 git add
將文件修改添加到暫存區,而後 git commit
提交更改,就把暫存區的全部內容提交到了當前分支的 Commit 歷史中去了。bash
該操做只能做用於 Commit,而不能做用於文件。同時,該操做會建立一個新的 Commit 來撤銷以前提交的更改,它不會去修改現有的歷史記錄。spa
換句話說,這個命令是安全的,它不會丟失 Commit 記錄,只會新增。code
這個命令相對來講就要複雜一點了,它可以同時做用於 Commit 和文件,用來撤銷尚未提交到遠程倉庫的改動。cdn
對於 Commit 來講,git reset
會移動 HEAD 的位置,而且還能夠變動暫存區和工做區,該操做有三個選項:blog
是否是有點繞,不要緊咱們實戰說話:開發
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 log
和 git status
命令,能夠看到 Commit 歷史中,HEAD 的位置已經修改到了提交 b 的位置,同時在工做目錄中咱們還能找到 c 文件,而且 c 文件被移出了暫存區,這就是 mixed
。it
接下來,咱們再次將 c 文件提交回去恢復成初始狀態,此次咱們在命令後加上 --soft
,咱們再來看,HEAD 的位置依然被修改了,而且工做區 c 文件依然存在,不一樣的是 c 依然在暫存區中。
最後咱們加上 --hard
再來看一看,咱們能夠發現,HEAD 變了,暫存區和工做區的 c 文件都被移除了,這個參數比較危險,也就不建議你們在公共分支上進行操做了。
說完了 Commit,那文件是如何撤銷的呢?對於文件來講,上面提到的三個參數是不起做用的,它會去更新暫存區的對應文件到指定 Commit 的時候的版本。
仍是上面的例子,若是我使用命令 git reset HEAD~1 c
,會出現什麼結果呢?你們能夠想想,答案是,它會將 c 文件更新到上一個 Commit 的時候的版本,也就是尚未被建立的狀態,因此你執行 git status
能夠發現暫存區中存在 delete: c
,這就是文件的撤銷。
當你 checkout Commit 的時候,會將 HEAD 指向你指定的 Commit,而且這個沒有分支指向這個 HEAD,因此 checkout 以後,會處於一個 detached HEAD 的分支,若是你要提交 Commit 到這個分支,你應該先 checkout 一個分支出來,而後再進行提交。
當你 checkout 文件的時候,checkout 命令和 reset 就有點相似,可是它不會更新暫存區,只會更新工做區,當你使用 git checkout <commit> <filename>
的時候,就會把工做區的對應文件更新到指定 Commit 版本的狀態,當你使用 git checkout -- <filename>
的時候就會撤銷掉在工做區這個文件的修改。
對於這些操做,你們必定要注意,不要亂用,把倉庫搞亂了就很差了。
很是感謝您的閱讀,歡迎關注、轉發、分享支持我。