git reset, git checkout, git revert 區(qū)別
團(tuán)隊(duì)中大多數(shù)成員使用 sourceTree 和 github 兩款 git 工具,然而大家對(duì)于圖形化工具提供的  reset,checkout,revert  功能點(diǎn)并不是很了解,甚至于混淆,然后憑借猜測(cè)去使用。功夫不負(fù)有心人,在嘗試過多次沖突處理或分支開發(fā)的坑后,終于形成了自己的一套使用方式,可喜可 賀。然而問題的解決方案的并不是效率***的,內(nèi)部的執(zhí)行過程我們也不清楚,這對(duì)于一個(gè)自律的程序藝術(shù)家是無法接受的?;谶@個(gè)問題,翻譯這篇博客,為  git 中高級(jí)用戶的 undo 操作提供參考。鼓勵(lì)在熟悉命令行操作再通過圖形化工具提高開發(fā)效率。水平有限,釋疑為主,翻譯為輔
Reset Checkout and Revert
原文地址:https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting
git reset, git checkout, git revert 命令是最有用的三條 git 命令。他們可以幫助你撤銷 repo 的一些操作,并且前兩條命令既可以用于 commit 級(jí)別,也可以用于 file 級(jí)別。
因?yàn)樗麄兒芟嗨?,所以很容易混淆。這片文章,我們將比較他們的相同和不同之處。
閱讀本文前需要了解 git  repo  的三大 components,分別是 working directory(代碼倉庫)  staged snapshot(快照:add的緩存庫)  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, 這可以用來撤銷當(dāng)前分支的一些 commit 。
例如,下面的命令會(huì)讓 `hotfix` 分支回退兩個(gè) commits
git checkout hotfix
git reset HEAD~2
先前在 HEAD 之前的兩次 commit 現(xiàn)在處在 HEAD 之后,這意味著他們?cè)谙乱淮?git 提交時(shí)被作為垃圾刪掉,換句話說這兩次提交會(huì)被拋棄。如下圖所示:
git reset用于撤銷未被提交到遠(yuǎn)端的改動(dòng)。除了可以移動(dòng)當(dāng)前分支的HEAD,你可以通過不同的標(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可撤銷所有緩存改動(dòng),但是保留他們?cè)诠ぷ髂夸浵隆?code>git reset --hard HEAD可徹底刪除沒有提交的改動(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,通過提供 commit Id 作為參數(shù).
比如下面的命令。
git checkout HEAD~2/[commit id]
這對(duì)于 review repo 的某個(gè) version 的代碼很有用。然而,如果再次添加新的提交就無法返回原先的狀態(tài)。因此,你應(yīng)該在修改前總是創(chuàng)建一個(gè)新的分支。
Revert
git revert 命令通過創(chuàng)建一次新的 commit 來撤銷一次 commit 所做出的修改。這種撤銷的方式是安全的,因?yàn)樗⒉恍薷?commitm history, 比如下邊的命令將會(huì)查出倒數(shù)第二次(即當(dāng)前commit的往前一次)提交的修改,并創(chuàng)建一個(gè)新的提交,用于撤銷當(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  類似,除了它會(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 | 不支持 | |















 
 
 










 
 
 
 