想成為Git大神?從學會reset開始吧

TechFlow2019發表於2020-12-29

大家好,今天我們來著重介紹一個非常關鍵的功能就是reset。在上一篇文章介紹修改歷史記錄的時候曾經提到過,當我們需要拆分一個歷史提交記錄的時候需要使用reset。估計很多小夥伴不明白,reset究竟做了什麼,所以在這篇文章當中我們來詳細聊聊。

git reset功能整體的操作分為三個步驟,我們拆分開來詳細介紹。

第一步(移動指標)

雖然reset有三個步驟,但是我們通過加入不同的引數,可以實現在不同的步驟退出。但是不管怎麼操作,第一步都是一定會執行的。

reset的第一步就是移動HEAD指標,HEAD指標我們都知道就是當前的工作目錄的指標。說到移動指標,我們可能會想起checkout,checkout的功能就是移動指標。我們不僅可以移動到另外的分支,也可以移動到之前某一次的提交記錄。

這是我們這個git專題的目錄,如果我們執行git checkout bee9ce,那麼我們的工作目錄會被重置到這個提交之後的狀態。而最新的add article 17這個commit的所有改動都會不可見,就好像發生了時間倒流一樣,我們回到了剛剛commit完add new articles的狀態。

reset雖然也一樣是移動HEAD指標,但是它對於移動之後的處理不同。reset之後我們的commit不是不可見而是被回滾了。

我們來做個實驗,現在我們在目錄當中建立一個test.txt檔案,我們把它commit。

然後我們執行git reset --soft HEAD~。

這裡的HEAD~我們應該都瞭解了,HEAD表示當前位置,~表示前一個位置。所以連起來就是表示reset到HEAD之前的一個提交。soft參數列示我們reset的時候只執行第一個步驟,也就是移動指標的步驟。

reset之後我們發現test.txt這個檔案並沒有消失,仍然還在暫存區當中,只不過還沒有被commit。這就是reset回滾commit的操作,它不會把改動抹除,但是會把commit取消。

第二步(更新暫存區)

如果我們在reset的時候加上了--soft的引數,它會在執行第一步結束之後就退出,後面的第二步和第三步都不會執行。

如果想要執行第二步,我們可以不傳任何引數,或者是指定--mixed。因為reset的預設引數就是--mixed。

第二個步驟是更新暫存區,前面我們看見了,如果只是移動指標,那麼在移動的時候會把中間的commit全部取消。雖然這些提交被取消了,但是它們對應的改動仍然存在,並且一樣存放在暫存區當中,相當於執行完git add之後的狀態。

如果我們繼續執行第二步,git會把暫存區也給重置,回到git add之前的狀態

如上圖所示,我們執行了git reset HEAD~之後再執行git status可以看到test.txt回到了被add之前的狀態。

第三步(回滾修改)

reset的最後一步是回滾修改,也就是在第二步的基礎上,進一步把改動全部抹除,回滾到沒有修改之前的狀態。如果需要實現這一點,需要加上--hard引數。

這是一個非常危險的操作,它不僅會回滾已經被commit的所有改動,並且還會強制覆蓋當前工作區,所有沒有被提交的改動也一樣會消失。只要是提交了的改動,即使reset了,也可以通過reflog找回來,但是如果沒有提交的就沒有辦法了,所有的改動都會消失。對於開發者來說,這是一個巨大的打擊,一定要切記慎重。

最後我們簡單總結一下reset的用法。

git reset --soft,只會回滾commit操作,所有的改動都會保留在暫存區。相當於回到了執行git commit之前。

git reset --mixed,不僅會回滾commit操作,也會回滾暫存區內的內容。相當於回到了執行git add之前。

git reset --hard,會回滾一切,重置工作區。相當於回到了改動之前,沒有被commit的內容會丟失

reset是一個很好用的功能,使用熟練可以起到非常大的作用,實現一些炫酷的功能。但是它也有很大的隱患,如果一不小心使用了--hard可能會導致一些悲劇發生。我就有過幾次不小心把剛寫完的程式碼回滾了的經歷,所以大家在使用的時候一定要千萬小心。

今天的文章就到這裡,衷心祝願大家每天都有所收穫。如果還喜歡今天的內容的話,請來一個三連支援吧~(點贊、關注、轉發

相關文章