git reset, git checkout, git revert 區(qū)別
團(tuán)隊(duì)中大多數(shù)成員使用 sourceTree 和 github 兩款 git 工具,然而大家對(duì)于圖形化工具提供的 reset,checkout,revert 功能點(diǎn)并不是很了解,甚至于混淆,然后憑借猜測(cè)去使用。功夫不負(fù)有心人,在嘗試過(guò)多次沖突處理或分支開(kāi)發(fā)的坑后,終于形成了自己的一套使用方式,可喜可 賀。然而問(wèn)題的解決方案的并不是效率***的,內(nèi)部的執(zhí)行過(guò)程我們也不清楚,這對(duì)于一個(gè)自律的程序藝術(shù)家是無(wú)法接受的?;谶@個(gè)問(wèn)題,翻譯這篇博客,為 git 中高級(jí)用戶(hù)的 undo 操作提供參考。鼓勵(lì)在熟悉命令行操作再通過(guò)圖形化工具提高開(kāi)發(fā)效率。水平有限,釋疑為主,翻譯為輔
Reset Checkout and Revert
原文地址:https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting
git reset, git checkout, git revert 命令是最有用的三條 git 命令。他們可以幫助你撤銷(xiāo) repo 的一些操作,并且前兩條命令既可以用于 commit 級(jí)別,也可以用于 file 級(jí)別。
因?yàn)樗麄兒芟嗨疲院苋菀谆煜?。這片文章,我們將比較他們的相同和不同之處。
閱讀本文前需要了解 git repo 的三大 components,分別是 working directory
(代碼倉(cāng)庫(kù)) staged snapshot
(快照:add的緩存庫(kù)) commit history
(commit歷史) ,這將更好的幫助你理解這三條命令。
commit 級(jí)別的操作
傳遞給 git reset
和 git checkout
的參數(shù)會(huì)決定命令的作用范圍。當(dāng)命令并不包括含一個(gè)文件路徑時(shí),命令作用于整個(gè) commit
。
Reset:
在 commit
級(jí)別上,git reset
命令移動(dòng) HEAD
到當(dāng)前分支的一個(gè) commit
, 這可以用來(lái)撤銷(xiāo)當(dāng)前分支的一些 commit
。
例如,下面的命令會(huì)讓 `hotfix` 分支回退兩個(gè) commits
git checkout hotfix
git reset HEAD~2
先前在 HEAD 之前的兩次 commit 現(xiàn)在處在 HEAD 之后,這意味著他們?cè)谙乱淮?git 提交時(shí)被作為垃圾刪掉,換句話(huà)說(shuō)這兩次提交會(huì)被拋棄。如下圖所示:
git reset用于撤銷(xiāo)未被提交到遠(yuǎn)端的改動(dòng)。除了可以移動(dòng)當(dāng)前分支的HEAD,你可以通過(guò)不同的標(biāo)記選擇修改 staged snapshot 或者 working directory
-
--soft
:staged snapshot
和working directory
都未被改變 (建議在命令行執(zhí)行后,再輸入 git status 查看狀態(tài)) -
--mixed
:staged snapshot
被更新,working directory
未被更改。【這是默認(rèn)選項(xiàng)】(建議同上) -
--hard
:staged snapshot
和working directory
都將回退。
--hard 很危險(xiǎn),它會(huì)直接回退你之前所有的修改,使用前,可以事先保存 commit id.
【這些標(biāo)記經(jīng)常和HEAD
一起使用。例如,git reset --mixed HEAD
可撤銷(xiāo)所有緩存改動(dòng),但是保留他們?cè)诠ぷ髂夸浵隆?code>git reset --hard HEAD可徹底刪除沒(méi)有提交的改動(dòng)?!?/p>
checkout
到現(xiàn)在為止,你應(yīng)該已經(jīng)熟悉 commit
級(jí)別的 git checkout
了。當(dāng)你傳送一個(gè) branch name
名字時(shí),你將更換當(dāng)前的分支.
git checkout hotfix
上面的命令會(huì)切換 HEAD 到不同的分支,并且更新當(dāng)前的 working directory
去匹配。因?yàn)闀?huì)覆蓋當(dāng)前的本地更改,所以更換分支前git
強(qiáng)制你徹底放棄或者提交存儲(chǔ)當(dāng)前的更改。不同于 git reset
, git checkout
不會(huì)廢棄任何分支或提交。
你也可以 checkout
到任何一次 commit
,通過(guò)提供 commit Id
作為參數(shù).
比如下面的命令。
git checkout HEAD~2/[commit id]
這對(duì)于 review
repo 的某個(gè) version 的代碼很有用。然而,如果再次添加新的提交就無(wú)法返回原先的狀態(tài)。因此,你應(yīng)該在修改前總是創(chuàng)建一個(gè)新的分支。
Revert
git revert
命令通過(guò)創(chuàng)建一次新的 commit
來(lái)撤銷(xiāo)一次 commit
所做出的修改。這種撤銷(xiāo)的方式是安全的,因?yàn)樗⒉恍薷?commitm history
, 比如下邊的命令將會(huì)查出倒數(shù)第二次(即當(dāng)前commit的往前一次)提交的修改,并創(chuàng)建一個(gè)新的提交,用于撤銷(xiāo)當(dāng)前提交的上一次 commit
。
git checkout hotfix
git revert HEAD~2
如下圖所示:
File 級(jí)別的操作
git reset
和 git checkout
命令同樣可以接受一個(gè)可選的文件路徑作為參數(shù),這樣可以將操作限制在一個(gè)單獨(dú)的文件中。
Reset:
當(dāng)調(diào)用一個(gè)文件路徑時(shí),git reset
命令會(huì)更新 staged snapshot
去匹配某次 commit
。 下面的命令將會(huì)使文件回退一個(gè) commit
。
git reset HEAD~1 [文件](不建議使用)
【--soft、--mixed、--hard標(biāo)記此時(shí)不起作用,會(huì)更新staged snapshot,但不更新working directory】
Checkout
git checkout
命令 和 git reset
類(lèi)似,除了它會(huì)更新 working directory
, 而不是 staged snapshot
如下命令將會(huì)更新 working directory
去匹配某次 commit
git checkout HEAD~1 [文件]
Summary:
commands | scope | common user cases | |
---|---|---|---|
git reset | Commit | Discard commits in a private branch or throw away uncommited changes | |
git reset | File | Unstage a file | |
git checkot | Commit | switch between branches or inspect old snapshot | |
git checkout | File | Discard changes in the working directory | |
git revert | commit | Undo commits in a public branch | |
git revert | File | 不支持 |