雖然git
誕生距今已有12
年之久,網上各類關於git
的介紹文章數不勝數,可是依然有不少人(包括我本身在內)對於它的功能不能徹底掌握。如下的介紹只是基於我我的對於git
的理解,而且可能生編硬造了一些不徹底符合git
說法的詞語。目的只是爲了讓git
通俗化,使初學者也能大概瞭解如何快速上手git
。同時,下面全部討論,咱們都假設只使用一個分支,也就是主分支master
的狀況,雖然這種做法並不符合git
規範,可是現實狀況中絕大部分用戶是直接在master
分支上進行工做的,因此在這裏咱們不去引入更加複雜的各類分支的狀況,也不涉及標籤tag
的操做,只講在最簡單的主分支上如何回退。git
正常狀況下,咱們的工做流就是3
個步驟,對應上圖中的3
個箭頭線:segmentfault
git add . git commit -m "comment" git push
git add .
把全部文件放入暫存區
;瀏覽器
git commit
把全部文件從暫存區
提交進本地倉庫
;編輯器
git push
把全部文件從本地倉庫
推送進遠程倉庫
。svn
git
之因此使人費解,主要是它相比於svn
等等傳統的版本管理工具,多引入了一個暫存區(Stage
)的概念,就由於多了這一個概念,而使不少人疑惑。其實,在初學者來講,每一個區具體怎麼工做的,咱們徹底不須要關心,而只要知道有這麼4
個區就夠了:工具
工做區(Working Area
)spa
暫存區(Stage
)code
本地倉庫(Local Repository
)blog
遠程倉庫(Remote Repository
)ip
以上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 @@ --- -layout: main +1234layout: main color: black ---
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 @@ --- -layout: main +1234layout: main color: black ---
這時候咱們看到的差別是暫存區
和本地倉庫
之間的差別。
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
這個命令的用法,今後你不再用擔憂提交錯誤了。
獨孤求敗:Git中的各類後悔藥