歡迎光臨
每天分享高質量文章

Git 的 4 個階段的撤銷更改

(點選上方藍字,快速關註我們)


來源:張京

www.fengerzh.com/git-reset/



雖然git誕生距今已有12年之久,網上各種關於git的介紹文章數不勝數,但是依然有很多人(包括我自己在內)對於它的功能不能完全掌握。以下的介紹只是基於我個人對於git的理解,並且可能生編硬造了一些不完全符合git說法的詞語。目的只是為了讓git通俗化,使初學者也能大概瞭解如何快速上手git。同時,下麵所有討論,我們都假設只使用一個分支,也就是主分支master的情況,雖然這種作法並不符合git規範,但是現實情況中絕大部分使用者是直接在master分支上進行工作的,所以在這裡我們不去引入更加複雜的各種分支的情況,也不涉及標簽tag的操作,只講在最簡單的主分支上如何回退。


基本概念


3個步驟



正常情況下,我們的工作流就是3個步驟,對應上圖中的3個箭頭線:


git add .

git commit –m “comment”

git push


  1. git add .把所有檔案放入暫存區;

  2. git commit把所有檔案從暫存區提交進本地倉庫;

  3. git push把所有檔案從本地倉庫推送進遠端倉庫。


4個區


git之所以令人費解,主要是它相比於svn等等傳統的版本管理工具,多引入了一個暫存區(Stage)的概念,就因為多了這一個概念,而使很多人疑惑。其實,在初學者來說,每個區具體怎麼工作的,我們完全不需要關心,而只要知道有這麼4個區就夠了:


  • 工作區(Working Area)

  • 暫存區(Stage)

  • 本地倉庫(Local Repository)

  • 遠端倉庫(Remote Repository)


5種狀態


以上4個區,進入每一個區成功之後會產生一個狀態,再加上最初始的一個狀態,一共是5種狀態。以下我們把這5種狀態分別命名為:


  • 未修改(Origin)

  • 已修改(Modified)

  • 已暫存(Staged)

  • 已提交(Committed)

  • 已推送(Pushed)


檢查修改


瞭解了基本概念之後,我們來談一談犯錯誤之後如何撤銷的問題。首先,我們要瞭解如何檢查這3個步驟當中每一個步驟修改了什麼,然後才好判斷有沒有修改成功。檢查修改的二級命令都相同,都是diff,只是引數有所不同。


已修改,未暫存


git diff


首先,我們來看一下,如果我們只是簡單地在瀏覽器裡儲存了一下檔案,但是還沒有做git add .之前,我們如何檢查有哪些修改。我們先隨便拿一個檔案來做一下實驗:



我們在檔案開頭的第2行胡亂加了4個數字1234,存檔,這時檔案進入了已修改狀態,但是還沒有進入暫存區,我們執行git diff,結果如下:


diff —git a/index.md b/index.md

index 73ff1ba..1066758 100644

— a/index.md

+++ b/index.md

@@ –1,5 +1,5 @@

layoutmain

+1234layoutmain

colorblack


git diff的結果告訴我們哪些檔案已經做了哪些修改。


已暫存,未提交


git diff –cached


現在我們把修改放入暫存區看一下。先執行git add .,然後執行git diff,你會發現沒有任何結果:



這說明git diff這個命令只檢查我們的工作區和暫存區之間的差異,如果我們想看到暫存區和本地倉庫之間的差異,就需要加一個引數git diff –cached:


diff —git a/index.md b/index.md

index 73ff1ba..1066758 100644

— a/index.md

+++ b/index.md

@@ –1,5 +1,5 @@

layoutmain

+1234layoutmain

colorblack


這時候我們看到的差異是暫存區和本地倉庫之間的差異。


已提交,未推送


git diff master origin/master


現在,我們把修改從暫存區提交到本地倉庫,再看一下差異。先執行git commit,然後再執行git diff –cached,沒有差異,執行git diff master origin/master,可以看到差異:



在這裡,master就是你的本地倉庫,而origin/master就是你的遠端倉庫,master是主分支的意思,因為我們都在主分支上工作,所以這裡兩邊都是master,而origin就代表遠端。


撤銷修改


瞭解清楚如何檢查各種修改之後,我們開始嘗試各種撤銷操作。


已修改,未暫存


如果我們只是在編輯器裡修改了檔案,但還沒有執行git add .,這時候我們的檔案還在工作區,並沒有進入暫存區,我們可以用:


git checkout .


或者


git reset –hard


來進行撤銷操作。



可以看到,在執行完git checkout .之後,修改已被撤銷,git diff沒有任何內容了。


一對反義詞 git add .的反義詞是git checkout .。做完修改之後,如果你想向前走一步,讓修改進入暫存區,就執行git add .,如果你想向後退一步,撤銷剛才的修改,就執行git checkout .。


已暫存,未提交


你已經執行了git add .,但還沒有執行git commit -m “comment”。這時候你意識到了錯誤,想要撤銷,你可以執行:


git reset

git checkout .


或者


git reset –hard


git reset只是把修改退回到了git add .之前的狀態,也就是說檔案本身還處於已修改未暫存狀態,你如果想退回未修改狀態,還需要執行git checkout .。


或許你已經註意到了,以上兩個步驟都可以用同一個命令git reset –hard來完成。是的,就是這個強大的命令,可以一步到位地把你的修改完全恢復到未修改的狀態。


已提交,未推送


你的手太快,你既執行了git add .,又執行了git commit,這時候你的程式碼已經進入了你的本地倉庫,然而你後悔了,怎麼辦?不要著急,還有辦法。


git reset –hard origin/master


還是這個git reset –hard命令,只不過這次多了一個引數origin/master,正如我們上面講過的,origin/master代表遠端倉庫,既然你已經汙染了你的本地倉庫,那麼就從遠端倉庫把程式碼取回來吧。


已推送


很不幸,你的手實在是太快了,你既git add了,又git commit了,並且還git push了,這時你的程式碼已經進入遠端倉庫。如果你想恢復的話,還好,由於你的本地倉庫和遠端倉庫是等價的,你只需要先恢複本地倉庫,再強制push到遠端倉庫就好了:


git reset —hard HEAD^

git push –f



總結


以上4種狀態的撤銷我們都用到了同一個命令git reset –hard,前2種狀態的用法甚至完全一樣,所以只要掌握了git reset –hard這個命令的用法,從此你再也不用擔心提交錯誤了。

覺得本文有幫助?請分享給更多人

關註「演演算法愛好者」,修煉程式設計內功

贊(0)

分享創造快樂