章節目錄git
前言github
1. 基礎篇:windows
Git的版本歷史記錄採用了與傳統集中式版本管理系統徹底不一樣的方式進行組織,在剛開始使用Git的時候咱們每每會不知所措,好比看到這樣的歷史記錄。安全
看到這個七拐八拐的圖形,你可能徹底不知道它表明了什麼。其實這正是Git的特別之處,Git之因此可以實現以前咱們所說那些靈活快速的操做,都是由於它採用這種相似鏈路的版本記錄方式。在這一篇中,咱們就一塊兒瞭解一下這個圖形是如何生成的。服務器
這裏,咱們要模擬一個常見的開發場景:微信
爲了演示這個過程,首先我使用 Visual Studio 建立了一個新的Web網站項目,完成了4次提交併推送到了TFS的Git倉庫。markdown
初始的歷史記錄顯示以下:併發
用簡單的示意圖表示,是這樣的:運維
若是使用命令行查看歷史記錄能夠鍵入以下命令ssh
>>> git log --oneline --graph
以上的–oneline參數讓git只輸出第一行的註釋信息,簡化歷史記錄更加可讀;–graph參數用來在命令行中輸出圖形鏈路,如今咱們還看不到效果,後面就會有變化。
輸出的結果以下
注:若是你在使用以上命令的過程當中遇到亂碼,請參考:常見問題#4
這表示當前的master分支指向版本庫最新的一次提交(C4),同時以前的全部提交都是順序完成的,造成了一個單一主線的鏈路。在TFS的版本記錄視圖上你所看到的圖形一列表示的是同一個意思。
如今,按照咱們在上一篇中介紹的方法,建立feature1分支,並在這上面完成2次新的提交。
此時再次使用上面的命令列出歷史記錄,你會看到以下結果:
這個時候你就會有點納悶了,爲何明明作了分支,歷史記錄仍然是單一的直線呢?不是應該分叉了嗎?看一下示意圖你就明白了。
Git確實記錄了你的分支信息,只不過它很是聰明的只是修改了feature1所指向的提交而已;這時你的master分支仍然指向C4提交,而feature1分支則指向C6提交了。
以上git log所輸出的信息中也很是明確的標明瞭這一點,看一下歷史記錄的第1行和第3行括號裏面內容就明白了。
如今那個討厭的項目經理給你下達了新的任務,要修復線上問題。由於線上所部署的正是master分支上的最新版本,因此你須要切換到master分支(也就是C4提交所表明的版本)進行修改。
這時你可使用如下命令完成hotfix分支的建立
>>> git checkout master >>> git checkout -b hotfix
完成這個操做後,咱們在hotfix分支上輸出歷史記錄。
你會看到如今hotfix和master分支同時指向了一個提交記錄(C4),示意圖以下:
如今咱們在hotfix分支上添加2個新的變動,並輸出歷史記錄
如今hotfix所指向的提交變成了 C8,若是再看咱們的示意圖就能夠看到分叉的效果了
可是爲何git 輸出的歷史記錄中仍然是一條直線呢?這是由於對於master, hotfix和feature1任何一個分支而言,他們的改動對於本身都是單向的惟一鏈路。
如今你已經完成了問題修復,能夠將代碼合併到master併發布到線上環境了,讓咱們將hotfix分支的代碼合併到master主幹上。你須要執行下面命令
>>> git checkout master >>> git merge hotfix
這2條命令的意思是回到master分支並將hotfix分支的改動合併進來,由於hotfix就是基於master分支進行的,因此合併會直接完成不會有任何的衝突出現。
這裏出現了一個詞Fast-forward,由於hotfix分支是直接在master分支上完成的,因此git其實僅僅修改了master分支的指向到hotfix的當前指向(也就是C8),輸出一下log你就看得很清楚了。
對比剛纔在hotfix上的log輸出,你會看到這裏惟一的變化就是本地master分支的指向移動到了最後一條提交上。你也許會注意到這裏還有一個origin/master的指向仍然在以前的提交之上,這時由於咱們的Git庫已經提交到了TFS的中心存儲庫,而這個origin/master所表明的是這個中心存儲庫上的master分支所處的位置,由於咱們在以上過程當中沒有給中心存儲庫推送過代碼,因此這個中心存儲庫的master分支仍然指向的是最初的位置。
到這裏你會明白,Git的分支其實就是一個指針而已,經過這個指針對提交的指向,Git能夠很是靈活的切換版本。
到了這裏,咱們的示意圖就變成了這個樣子了
如今你已經修復了線上問題,能夠回到feature1上繼續工做了。假設咱們提交C9之後feature1的開發工做也已經完成能夠合併了。與剛纔合併hotfix的方法同樣,咱們只須要返回master分支並執行合併命令
>>> git checkout master >>> git merge feature1
執行的效果以下:
如今若是咱們再次在master上輸出歷史記錄,你將看到以下效果
你會注意到git建立了一個新的提交 b5bcb0b 並將這個提交的註釋設置爲 Merge branch ‘feature1’,它的意思是我爲你建立了一個新的提交,在這個提交裏面保存了feature1合併進來的代碼變動。
注意:在執行merge動做的時候出現了3個Auto-merging的信息,這代表Git自動爲你完成了3個文件的合併,在實際使用中這樣作多是會出現問題的,由於Git實際上只是根據文件代碼行的信息判斷是否能夠完成自動合併,這種合併並非永遠安全可靠的。這一點咱們在進階篇中會特別介紹。
如今,咱們的示意圖就變成了這個樣子
最後,咱們能夠同步代碼到TFS中心存儲庫,並查看服務器上的歷史記錄。你會看到與咱們的示意圖很是相似的圖形顯示。
瞭解Git處理歷史記錄的方式對於咱們用好Git很是重要,特別是在企業級開發中處理複雜的多版本並行開發的過程當中。以上咱們提到的幾個可能令你困惑的地方,好比hotfix分支合併的時候Git僅僅移動指針的行爲,以及最後合併feature1分支時Git建立用於合併的提交的方式都是咱們在平常開發中常見的狀況。理解了Git的特殊處理方式有助於你在遇到相似狀況的時候做出正確的判斷,並對後面介紹的不少複雜場景更容易理解。
示例代碼:
以上示例代碼已經推送到 https://github.com/lean-soft/git-history-demo
參考:
相關文章:
請關注微信公衆號 【devopshub】,獲取更多關於DevOps研發運維一體化的信息