g4e基础篇#6 了解Git历史记录
Git的版本歷史記錄采用了與傳統集中式版本管理系統完全不同的方式進行組織,在剛開始使用Git的時候我們往往會不知所措,比如看到這樣的歷史記錄。
看到這個七拐八拐的圖形,你可能完全不知道它代表了什么。其實這正是Git的特別之處,Git之所以能夠實現之前我們所說那些靈活快速的操作,都是因為它采用這種類似鏈路的版本記錄方式。在這一篇中,我們就一起了解一下這個圖形是如何生成的。
這里,我們要模擬一個常見的開發(fā)場景:
你正在開發(fā)一個網站的某個新功能,按照Git的推薦方式,你創(chuàng)建了feature1分支來承載這個新功能的代碼變更。
當你已經在這個功能上完成幾次代碼提交的時候,你的項目經理告訴你這個網站現在出現了一個嚴重的線上問題,需要緊急修復。
為了能夠快速修復這個線上問題,你不能等待下一個版本發(fā)布,必須在現有線上版本上進行修復。這時你暫停了feature1分支的開發(fā)工作,切換回到master分支,從新拉取一個名為hotfix的分支并在這個分支上開始了線上問題的修復。
當你完成了修復并測試通過后,你將hotfix分支合并到master以便立即從新發(fā)布線上版本。
完成以上工作后,你切換回到feature1分支繼續(xù)進行新功能的開發(fā)直到新的功能也經過測試可以發(fā)布。
最后你將feature1分支也合并回到master分支,發(fā)布到線上環(huán)境。
為了演示這個過程,首先我使用 Visual Studio 創(chuàng)建了一個新的Web網站項目,完成了4次提交并推送到了TFS的Git倉庫。
初始狀態(tài)
初始的歷史記錄顯示如下:
用簡單的示意圖表示,是這樣的:
如果使用命令行查看歷史記錄可以鍵入如下命令
>>> git log --oneline --graph以上的–oneline參數讓git只輸出第一行的注釋信息,簡化歷史記錄更加可讀;–graph參數用來在命令行中輸出圖形鏈路,現在我們還看不到效果,后面就會有變化。
輸出的結果如下
注:如果你在使用以上命令的過程中遇到亂碼,請參考:常見問題#4
這表示當前的master分支指向版本庫最新的一次提交(C4),同時之前的所有提交都是順序完成的,形成了一個單一主線的鏈路。在TFS的版本記錄視圖上你所看到的圖形一列表示的是同一個意思。
創(chuàng)建feature1分支并提交2次變更
現在,按照我們在上一篇中介紹的方法,創(chuàng)建feature1分支,并在這上面完成2次新的提交。
此時再次使用上面的命令列出歷史記錄,你會看到如下結果:
這個時候你就會有點納悶了,為什么明明做了分支,歷史記錄仍然是單一的直線呢?不是應該分叉了嗎?看一下示意圖你就明白了。
Git確實記錄了你的分支信息,只不過它非常聰明的只是修改了feature1所指向的提交而已;這時你的master分支仍然指向C4提交,而feature1分支則指向C6提交了。
以上git log所輸出的信息中也非常明確的標明了這一點,看一下歷史記錄的第1行和第3行括號里面內容就明白了。
創(chuàng)建hotfix分支并提交另外2次變更
現在那個討厭的項目經理給你下達了新的任務,要修復線上問題。因為線上所部署的正是master分支上的最新版本,所以你需要切換到master分支(也就是C4提交所代表的版本)進行修改。
這時你可以使用以下命令完成hotfix分支的創(chuàng)建
>>> git checkout master >>> git checkout -b hotfix完成這個操作后,我們在hotfix分支上輸出歷史記錄。
你會看到現在hotfix和master分支同時指向了一個提交記錄(C4),示意圖如下:
現在我們在hotfix分支上添加2個新的變更,并輸出歷史記錄
現在hotfix所指向的提交變成了 C8,如果再看我們的示意圖就可以看到分叉的效果了
但是為什么git 輸出的歷史記錄中仍然是一條直線呢?這是因為對于master, hotfix和feature1任何一個分支而言,他們的改動對于自己都是單向的唯一鏈路。
合并hotfix分支到master
現在你已經完成了問題修復,可以將代碼合并到master并發(fā)布到線上環(huán)境了,讓我們將hotfix分支的代碼合并到master主干上。你需要執(zhí)行下面命令
>>> 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分支到master分支
現在你已經修復了線上問題,可以回到feature1上繼續(xù)工作了。假設我們提交C9以后feature1的開發(fā)工作也已經完成可以合并了。與剛才合并hotfix的方法一樣,我們只需要返回master分支并執(zhí)行合并命令
>>> git checkout master >>> git merge feature1執(zhí)行的效果如下:
現在如果我們再次在master上輸出歷史記錄,你將看到如下效果
你會注意到git創(chuàng)建了一個新的提交?b5bcb0b?并將這個提交的注釋設置為 Merge branch ‘feature1’,它的意思是我為你創(chuàng)建了一個新的提交,在這個提交里面保存了feature1合并進來的代碼變更。
注意:在執(zhí)行merge動作的時候出現了3個Auto-merging的信息,這表明Git自動為你完成了3個文件的合并,在實際使用中這樣做可能是會出現問題的,因為Git實際上只是根據文件代碼行的信息判斷是否可以完成自動合并,這種合并并不是永遠安全可靠的。這一點我們在進階篇中會特別介紹。
現在,我們的示意圖就變成了這個樣子
最后,我們可以同步代碼到TFS中心存儲庫,并查看服務器上的歷史記錄。你會看到與我們的示意圖非常類似的圖形顯示。
小結
了解Git處理歷史記錄的方式對于我們用好Git非常重要,特別是在企業(yè)級開發(fā)中處理復雜的多版本并行開發(fā)的過程中。以上我們提到的幾個可能令你困惑的地方,比如hotfix分支合并的時候Git僅僅移動指針的行為,以及最后合并feature1分支時Git創(chuàng)建用于合并的提交的方式都是我們在日常開發(fā)中常見的情況。理解了Git的特殊處理方式有助于你在遇到類似情況的時候作出正確的判斷,并對后面介紹的很多復雜場景更容易理解。
示例代碼:
以上示例代碼已經推送到?https://github.com/lean-soft/git-history-demo
相關文章:
g4e基礎篇#1 為什么要使用版本控制系統
g4e基礎篇#2 Git分布式版本控制系統的優(yōu)勢
g4e基礎篇#3 Git安裝與配置
g4e基礎篇#4 了解Git存儲庫(Repo)
g4e基礎篇#5 創(chuàng)建分支和保存代碼
原文地址:http://devopshub.cn/2018/01/30/g4e-basic-06-understand-git-history/
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的g4e基础篇#6 了解Git历史记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开源纯C#工控网关+组态软件(八)表达式
- 下一篇: Ray框架QA