1. 程式人生 > >g4e基礎篇#6 了解Git歷史記錄

g4e基礎篇#6 了解Git歷史記錄

ron 表示 git merge none 這一 如果 代碼 工具 lin

章節目錄

前言

1. 基礎篇:

  • 為什麽要使用版本控制系統
  • Git 分布式版本控制系統的優勢
  • Git 安裝和設置
  • 了解Git存儲庫(Repo)
  • 起步 1 – 創建分支和保存代碼
  • 起步 2 – 了解Git歷史記錄
  • 起步 3 – 拉取請求 Pull Request 工作機制

Git的版本歷史記錄采用了與傳統集中式版本管理系統完全不同的方式進行組織,在剛開始使用Git的時候我們往往會不知所措,比如看到這樣的歷史記錄。

技術分享圖片

看到這個七拐八拐的圖形,你可能完全不知道它代表了什麽。其實這正是Git的特別之處,Git之所以能夠實現之前我們所說那些靈活快速的操作,都是因為它采用這種類似鏈路的版本記錄方式。在這一篇中,我們就一起了解一下這個圖形是如何生成的。

這裏,我們要模擬一個常見的開發場景:

  • 你正在開發一個網站的某個新功能,按照Git的推薦方式,你創建了feature1分支來承載這個新功能的代碼變更。
  • 當你已經在這個功能上完成幾次代碼提交的時候,你的項目經理告訴你這個網站現在出現了一個嚴重的線上問題,需要緊急修復。
  • 為了能夠快速修復這個線上問題,你不能等待下一個版本發布,必須在現有線上版本上進行修復。這時你暫停了feature1分支的開發工作,切換回到master分支,從新拉取一個名為hotfix的分支並在這個分支上開始了線上問題的修復。
  • 當你完成了修復並測試通過後,你將hotfix分支合並到master以便立即從新發布線上版本。
  • 完成以上工作後,你切換回到feature1分支繼續進行新功能的開發直到新的功能也經過測試可以發布。
  • 最後你將feature1分支也合並回到master分支,發布到線上環境。

為了演示這個過程,首先我使用 Visual Studio 創建了一個新的Web網站項目,完成了4次提交並推送到了TFS的Git倉庫。

初始狀態

初始的歷史記錄顯示如下:

技術分享圖片

用簡單的示意圖表示,是這樣的:

技術分享圖片

如果使用命令行查看歷史記錄可以鍵入如下命令

>>> git log --oneline --graph

以上的–oneline參數讓git只輸出第一行的註釋信息,簡化歷史記錄更加可讀;–graph參數用來在命令行中輸出圖形鏈路,現在我們還看不到效果,後面就會有變化。

輸出的結果如下

技術分享圖片

註:如果你在使用以上命令的過程中遇到亂碼,請參考:常見問題#4

這表示當前的master分支指向版本庫最新的一次提交(C4),同時之前的所有提交都是順序完成的,形成了一個單一主線的鏈路。在TFS的版本記錄視圖上你所看到的圖形一列表示的是同一個意思。

創建feature1分支並提交2次變更

現在,按照我們在上一篇中介紹的方法,創建feature1分支,並在這上面完成2次新的提交。

此時再次使用上面的命令列出歷史記錄,你會看到如下結果:

技術分享圖片

這個時候你就會有點納悶了,為什麽明明做了分支,歷史記錄仍然是單一的直線呢?不是應該分叉了嗎?看一下示意圖你就明白了。

技術分享圖片

Git確實記錄了你的分支信息,只不過它非常聰明的只是修改了feature1所指向的提交而已;這時你的master分支仍然指向C4提交,而feature1分支則指向C6提交了。

以上git log所輸出的信息中也非常明確的標明了這一點,看一下歷史記錄的第1行和第3行括號裏面內容就明白了。

創建hotfix分支並提交另外2次變更

現在那個討厭的項目經理給你下達了新的任務,要修復線上問題。因為線上所部署的正是master分支上的最新版本,所以你需要切換到master分支(也就是C4提交所代表的版本)進行修改。

這時你可以使用以下命令完成hotfix分支的創建

>>> git checkout master
>>> git checkout -b hotfix

完成這個操作後,我們在hotfix分支上輸出歷史記錄。

技術分享圖片

你會看到現在hotfix和master分支同時指向了一個提交記錄(C4),示意圖如下:

技術分享圖片

現在我們在hotfix分支上添加2個新的變更,並輸出歷史記錄

技術分享圖片

現在hotfix所指向的提交變成了 C8,如果再看我們的示意圖就可以看到分叉的效果了

技術分享圖片

但是為什麽git 輸出的歷史記錄中仍然是一條直線呢?這是因為對於master, hotfix和feature1任何一個分支而言,他們的改動對於自己都是單向的唯一鏈路。

合並hotfix分支到master

現在你已經完成了問題修復,可以將代碼合並到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分支到master分支

現在你已經修復了線上問題,可以回到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

參考:

https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6


相關文章:

  • DevOps文檔中心的技術實踐演進
  • 微軟研發雲全家桶VSTS登陸中國
  • Markdown/reST 文檔發布流水線
  • 幾款好用的Git GUI客戶端工具
  • 使用 SSH 連接 TFS/VSTS 的GIT倉庫
  • GitHub + VSTS 開源代碼雙向同步

請關註微信公眾號 【devopshub】,獲取更多關於DevOps研發運維一體化的信息

?技術分享圖片

g4e基礎篇#6 了解Git歷史記錄