git reset與git revert是git與版本回退有關(guān)的兩個命令,本文將通過實(shí)驗(yàn)來測試這兩個命令之間的區(qū)別。接下來我們分別來看下這兩個命令
git reset:重置
git reset的作用是還原Index的狀態(tài)或修改本地分支HEAD的位置。有三種參數(shù)可以選擇
git reset --mixed
git reset --soft
git reset --hard
- git reset --mixed:此為默認(rèn)方式,不帶任何參數(shù)的git reset,即時(shí)這種方式,它回退到某個版本,只保留源碼,回退commit和index信息
- git reset --soft:回退到某個版本,只回退了commit的信息,不會恢復(fù)到index file一級。如果還要提交,直接commit即可
- git reset --hard:徹底回退到某個版本,本地的源碼也會變?yōu)樯弦粋€版本的內(nèi)容
下面將通過一個實(shí)驗(yàn)來看看實(shí)際情況下hard和soft參數(shù)有什么區(qū)別
-
首先我們新建一個文件 testReset.js,里面只有一行console.log("first version").將它提交到git上
-
然后將"first version"分別修改為"second version"和"third version",并提交兩次
-
此時(shí)使用git log命令查看提交記錄,會發(fā)現(xiàn)3條提交歷史
這時(shí)我們執(zhí)行命令
git reset --soft HEAD^
HEAD指的是當(dāng)前版本,^即指上一個版本,^^即指上兩個版本,也可以使用~1,~2以此類推來表示。
執(zhí)行完上述命令之后,通過git status和git log命令來查看當(dāng)前暫存區(qū)和提交記錄的狀態(tài)

我們可以看到,此時(shí)暫存區(qū)中有已經(jīng)暫存的testReset的修改狀態(tài),而此時(shí)文件中的代碼還是第三個版本的console.log("third version").但是第三次提交的記錄已經(jīng)不存在了,只剩下第一次和第二次提交的記錄
-
由于此時(shí)第三次改動已經(jīng)暫存,我們直接使用git commit命令來提交,回復(fù)到第三個版本,此時(shí)提交記錄變?yōu)?次
接著執(zhí)行命令
git reset --hard HEAD^
執(zhí)行完之后接著使用git status和git log命令查看當(dāng)前的狀態(tài)

此時(shí)可以看到,和之前soft參數(shù)執(zhí)行的結(jié)果相比,第三次提交的記錄同樣被刪除了,但是暫存區(qū)是clean干凈的,此時(shí)如果我們查看testReset.js文件會發(fā)現(xiàn),文件中的代碼已經(jīng)被還原成了第二個版本的console.log("second version").

通過這個例子我們可以看出git reset --soft和git reset --hard的區(qū)別,使用soft參數(shù)不會回退本地代碼,并且會將所有的改動移動到暫存區(qū);而hard參數(shù)則顯得比較“徹底”,它會抹去所有的提交記錄、代碼并且重置暫存區(qū)。因此hard參數(shù)要慎用
git revert:撤銷
git revert原理:根據(jù)你要回退的提交所做的改動做相反的改動,然后重新提交代碼,使代碼達(dá)到?jīng)]有這些舊提交所能達(dá)到的狀態(tài)。
具體來說,比如之前某個提交加了一行代碼,那么回退就是在相同位置減一行代碼,git只是根據(jù)舊提交反著做了一遍,這樣就相當(dāng)于是“還原”到了之前的某個版本
還是回到剛才的實(shí)驗(yàn),這次來看看git revert命令的效果
-
首先將當(dāng)前提交的狀態(tài)回到第三個版本
-
執(zhí)行命令
git revert HEAD,注意這里與git reset的區(qū)別,這里revert后面的head可以理解為從某個版本開始回退到上一個版本,因此如果執(zhí)行revert HEAD^的話,實(shí)際上是回退到上上個版本。這里會彈出一個vim編輯窗口,用于輸入回退提交信息
-
revert結(jié)束之后,使用git status和git log命令查看當(dāng)前狀態(tài)
此時(shí)可以發(fā)現(xiàn),前三次的提交記錄依然存在,但是多了一條revert的提交歷史,而且此時(shí)本地文件也回到了第二個版本(與當(dāng)前版本一致,所以暫存區(qū)是clean的)。
結(jié)語
通過上述例子,我們可以看出git revert和git reset的區(qū)別:git reset會將版本的指針向后移動,相當(dāng)于減少了版本,而git revert是將版本向前新增,會保留之前的提交記錄,新增版本。這是二者最大的區(qū)別,在實(shí)際工作中,我們需要根據(jù)不同的情況,謹(jǐn)慎地選擇這兩個命令及其參數(shù)






