GIT是非常優秀的版本控制工具,但是苦于git那晦澀難懂的man pages,還有眾多的命令選項和怪異的用法,git有點難學。這篇文章分享我學習過程中收藏的一些好圖,并圍繞這些圖講講我對git的理解,希望對大家有所幫助。
GIT工作流程
了解git,首先要弄清楚對象在被git管理過程中所處的4個階段,分別是:工作目錄、index(又稱為暫存區)、本地倉庫和遠程倉庫。一開始接觸這些概念可能比較繞,其實在git入門階段,可以先拋開遠程倉庫不看,只了解管理本地倉庫的”3棵樹”就夠了。如下圖:
常用GIT命令
在開始之前,我們需要把下面的圖看懂:
HEAD,頭,它始終指向當前所處分支的最新的提交點。你所處的分支變化了,或者產生了新的提交點,HEAD就會跟著改變。
working directory,它是你的工作目錄,也是當前你看到的東西。你的工作目錄是與版本、分支相關的。
stage的東西雖然看不見,但是執行git status就會看到哪些對象的修改將在下一次commit的時候被放進本地倉庫。這些東西稱為stage。
commit
commit把暫存區的內容存入到本地倉庫,并使得當前分支的HEAD向后移動一個提交點。如果對最后一次commit不滿意,可以使用git commit --amend來進行撤銷,修改之后再提交。如圖所示的,ed489被4ca87取代,但是git log里看不到ed489的影子,這也正是amend的本意:原地修改,讓上一次提交不露痕跡。
checkout
checkout用來檢出并切換分支。checkout成功后,HEAD會指向被檢出分支的最后一次提交點。對應的,工作目錄、暫存區也都會與當前的分支進行匹配。下圖是執行git checkout maint后的結果:
reset
reset命令把當前分支指向另一個位置,并且相應的變動工作目錄和索引。如下圖,執行git reset HEAD~3后,當前分支相當于回滾了3個提交點,由ed489回到了b325c:
reset有3種常用的模式:
–soft,只改變提交點,暫存區和工作目錄的內容都不改變
–mixed,改變提交點,同時改變暫存區的內容。這是默認的回滾方式
–hard,暫存區、工作目錄的內容都會被修改到與提交點完全一致的狀態
diff
我們在commit、merge、rebase、打patch之前,通常都需要看看這次提交都干了些什么,于是diff命令就派上用場了:
來比較下上圖中5種不同的diff方式:
比較不同的提交點之間的異同,用git diff 提交點1 提交點2
比較當前分支與其他分支的異同,用git diff 其他分支名稱
在當前分支內部進行比較,比較最新提交點與當前工作目錄,用git diff HEAD
在當前分支內部進行比較,比較最新提交點與暫存區的內容,用git diff --cached
在當前分支內部進行比較,比較暫存區與當前工作目錄,用git diff
看起來有點復雜?是的,記不住的時候就看看這些圖吧。
merge
merge命令把不同的分支合并起來。如下圖,HEAD處于master分支的ed489提交點上,other分支處于33104提交點上,項目負責人看了下覺得other分支的代碼寫的不錯,于是想把代碼合并到master分支,因此直接執行git merge other,如果沒有發生沖突,other就成功合并到master分支了。
rebase
rebase又稱為衍合,是合并的另外一種選擇。merge把兩個分支合并到一起進行提交,無論從它們公共的父節點開始(如上圖,other分支與master分支公共的父節點b325c),被合并的分支(other分支)發生過多少次提交,合并都只會在當前的分支上產生一次提交日志,如上圖的f8bc5。所以merge產生的提交日志不是線性的,萬一某天需要回滾,就只能把merge整體回滾。而rebase可以理解為verbosely merge,完全重演下圖分支topic的演化過程到master分支上。如下圖:
原文轉自:http://nettedfish.sinaapp.com/blog/2013/08/05/deep-into-git-with-diagrams/