Git基礎概念與Flow流程介紹

本文會分爲兩部分講解,第一部分介紹Git的基礎概念、常見客戶端、常用命令,是一個基礎說明。第二部分介紹Git的管理流程,主要是GitFlow,Github Flow、Gitlab Flow和ExeFlow四種。

Git相關

基本概念

Git是一個基於GNU協議的開源分佈式版本控制系統,是由Linux的創始人Linus Torvalds在2005爲了進行Linux內核的研發時自己編寫的。不同於之前的大部分客戶端-服務器模式的代碼管理系統,在每臺電腦上的每個Git目錄都是一個完整的代碼倉庫,包含了歷史所有的提交記錄並且可以完整查看所有版本,而不需要有服務器或者網絡連接。
2019年9月Git的當前的最新版本爲2.23.0.

常見客戶端

TortoiseGit

TortoiseGit,就是我們俗稱小烏龜。他們爲Svn也提供了很優秀的windows客戶端。而且這是一個開源的軟件,當前最新的版本位2.8.0 。
安裝之後會自動注入系統的右鍵菜單,在任何路徑右擊之後都會出現

如圖的選項,這是在非git倉庫時。當在git倉庫右鍵點擊時完整菜單如下

查看提交記錄

Sourcetree

Sourcetree是Atlassian提供的一款免費的Git客戶端工具,目前的版本是3.2.6。
安裝之後直接打開客戶端使用,整體界面大致如圖。

Intellij Idea

Idea是Java開發非常熱門的IDE,其中也集成了多種SCM工具,自然也包括Git的客戶端,整體的使用感受還是不錯的。

命令行

最後名不符實的再加上一個命令行吧,有很多同學還是習慣手敲命令的。

常用命令

存儲區域

Git主要有四塊存儲區域:

  • Workspace:工作區
  • Index / Stage:暫存區
  • Repository:倉庫區(或本地倉庫)
  • Remote:遠程倉庫
    工作區是本地計算機存儲,平時項目代碼存儲的地方。
    暫存區也是在本地存儲,當你在修改代碼但是還沒有執行commit操作時臨時存放你的改動,事實上它只是一個文件,保存即將提交到文件列表信息。
    倉庫區就是本地版本庫,這裏面有你提交到所有版本的數據。其中HEAD指向最新放入倉庫的版本。
    遠程倉庫就是比如Gitlab或者Github等。
    幾個存儲區域之間的工作流程一般是這樣:

還有另外一個版本的流程:

命令之 add & commit &push

add & commit 實際上就是一個文件加入版本控制的過程,在受git管理的目錄下新建一個文件,首先要將它標記爲add,接下來commit到本地的倉庫,就完成了本地的版本管理。
之後可以選擇是否執行push操作,如果執行就是將本地的變更提交到遠程服務器上,這樣別人就可以獲取到你的更新了。

命令之 branch & checkout

branch是常見的創建分支應用的語法,git和傳統的cs模式的SCM的工具相比branch的代價是非常小的,影響也是非常小的。git的branch可以只存在與本地,輕易和合並與刪除。

上圖就是很多Flow流程中可能存在的多個分支(實際上這些分支本地和遠程都是存在的)。
我們本地的一個項目可能就會存在多個分支,我們使用checkout命令,簽出一個分支之後,環境中的文件都會變爲該分支的相關文件。

命令之 cherry-pick

pick是挑選的意思,我們看一下示意圖

這是要求將 bugFix 分支上的 C3 、side 分支上的 C4 以及another分支上的C7通過cherry-pick的形式拿到 master分支上。這是很典型的一個使用cherry-pick的場景,bug修復的合併。

命令之 merge & rebase

通過上面的branch和push,我們已經切出不同的分支並且提交了,接下來就是要合併我們的提交內容到主分支上,這時我們可能會面臨兩個命令選擇 merge和rebase。
這兩個命令有什麼區別呢?我們通過一個模擬界面來看一下:
使用merge命令

使用rebase命令

建議:
rebase會把你當前分支的 commit 放到公共分支的最後面,所以叫變基。就好像你從公共分支又重新拉出來這個分支一樣。
merge 會把公共分支和你當前的commit 合併在一起,形成一個新的 commit 提交。
爲什麼建議使用rebase,因爲通常我們是feature分支基於master分支進行rebase,master是長期固定分支,feature是臨時分支,我們不希望因爲臨時分支的變更影響到master分支的提交記錄,而且通常情況下master分支是鎖定不允許直接提交的。所以建議大家使用rebase,這樣能夠在不影響master分支的情況下還能夠合併最新的內容。

Flow相關

我們這裏主要講四種flow進行對比,GitFlow,GitHub Flow,GitLab Flow,ExeFlow
我對於項目管理的核心理解有兩點:

  • 需求邊界
  • 時間邊界
    也就是一次迭代,就是在規定的時間邊界與規定的需求邊界範圍內完成。如果兩方面都能夠保質保量,自然沒有問題。其實那種Flow我覺得差異不算很大。但是當其中有一點無法滿足時,不同的Flow能夠達到的效果就不同了。這點自然是不同的企業有不同的場景與要求,有的企業可以拖延時間(工期),但是一定要保證規劃內的需求全部開發測試完成。有的公司則是對時間節點的要求更高,可以減少某些需求,但是一定要在規定時間點發布上線。我們在理解每種flow時,也會對項目管理的兩點影響說明一下。

GitFlow

GitFlow來源應該是 Vincent Driessen 在2010年1月發表的這篇《A successful Git branching model》,基本是現在Git中最出名的流程管理方法了。

我整理了其對應的流程圖,其中加粗的是指長期分支。可以看到master和develop是其中的長期分支,對外的發佈基於master分支,對內的研發基於develop分支。需要發佈版本時,是從develop分支切出release分支,最終合併至master。所以我理解在GitFlow中,最重要的實際上是develop分支,它承載了實際功能的開發修正和發佈,而master最大的作用有兩個,一是發佈,二是熱修正(hotfix)。
GitFlow的流程我理解時偏重時間,而非需求的。也就是說如果臨近發佈時間,而需求沒有完成,其唯一的選擇就是延期,因爲按照流程,release分支是從develop分支切出,如果測試的環境是基於develop,很可能是沒有打到發佈標準的,所以只能等打到發佈標準後才能進行後續步驟。但是好處在於開發只用基於develop分支,很難出現漏合併代碼或者bug修正之類的情況。我也覺得這份流程在大型企業內部是比較難推進的,因爲它的環境管理還不夠,它的release、master分別對應預發佈和正式環境,develop我覺得還不夠清晰,因爲這塊我們通常是需要兩個環境,開發和測試環境。所以對於多環境管理我覺得是需要根據不同的企業的要求進行改造的。

GitHub Flow

顧名思義,GitHub Flow就是GitHub推薦的管理流程

可以看到,只能用簡單2字形容,只有master和feature兩個分支概念,其中master是長期分支。所以我還加上了Github官方的一些說明。
我覺得這不是一份可以用於企業級複雜項目管控的Git 流程,最基礎的就是沒有多環境管理,無法想象多角色配合時只基於master分支如何進行。master究竟用於測試環境還是隨時可發佈的正式環境呢?其次這份流程應該也是偏重於需求而非時間。理由和GitFlow一樣。
我覺得GitHub推出的這份flow主要是應用於其平臺上大部分託管的小型開源項目,並且儘量結合平臺提供的其他組件。對於企業內部不夠合適。

GitLab Flow

GitLab Flow自然是基於GitLab環境的flow管理流程

這個Flow實際上最核心的分支是基於master,生產環境是production,預發佈環境是pre-production。我覺得對於多環境的問題實際上和GitFlow很相似,也是開發和測試環境不夠清晰。
提交、審覈基於GitLab的MR進行。截圖的部分就是GitLab官方的MR的說明。
GitLab Flow與GitFlow的差別我覺得僅僅在於master與develop的分支命名,還有就是加入了MR(但是由於GitFlow不基於任何服務端環境,所以這塊是可以整合的),問題也很相似。

ExeFlow

由於上面幾種Flow在時間和需求都是選擇了需求而延遲了時間,我也順便講一下選擇時間而放棄一些需求的Flow流程吧。
這是我之前一家公司的流程設計,服務端是GitLab。
實際工作場景:
我們的系統由於主要是面向大型企業內部使用,存在複雜的分發流程和權限控制,經過長時間的累積業務模型也很複雜各種關聯和引用,所以有一些大型任務的開發週期可能會比較長,到達2-3個月的週期。
我們的迭代週期正常是1個月。流程大概如下:

  • 上月末進行迭代計劃評估與安排,這裏會確認下月迭代目標的Story內容與數據。各自主管進行子任務的拆分評估與排期。
  • 開發時間一般是2周,我們基本是會在月中設定研發截止線,所有研發任務要在截止線前完成提測。期間有完成的任務可以隨時提測。【涉及分支:Feature,Local,Develop】
  • 完整的系統集成測試時間一般是安排在第三週,測試會進行全面的測試。本週研發的主要任務一方面是處理Bug,一方面可以介入下月迭代大項的需求說明與分析。【涉及分支:Feature,Local,Develop】
  • 第四周的前三天,我們會切出預發佈的分支在第四周週一時,會給出明確本次能夠上線的Story List,不在清單內的都不允許合併只預發佈環境(也就是我們實際上運行需求在預發佈之前仍舊有變更,只要測試人員通過了集成測試環境,就可以合併並且發佈),本次發版的具體內容和通知也是當天發出。【涉及分支:Feature,Release】
  • 發版一般安排在當月的最後一個週四(爲了防止有線上問題,所以不能是週五第二天會沒有人員值守)。【涉及分支:Release,Master】

流程圖:

這裏有幾個特點:

  • develop對於測試環境,local對應開發聯調環境。
  • 所有的分支起始時都是由master分支切出
  • 固定長期分支有三個:master,develop,local
  • 所有的分支不能直接向master提交,必須通過release驗證後合併至master。
  • master分支鎖定需要權限審覈提交
  • release是臨時分支,指定時間從master切出,直接從feature合併。

先來說說有點,根據之前提供的流程來看,我們企業要求的是時間保障而需求可以調整。所以在指定時間節點到來時,我們會確定一份可以發佈的需求清單,根據這份清單來合併至release,從而最終能夠發佈。這是一個比較典型的保時間點,放需求的流程管理。
但是這個會有下面幾個問題:

  • develop和local分支從master切出後,長期和master不同步,所以需要定期的rebase,否則會產生很多環境不一致導致的問題。
  • hotfix或者feature提交之後的bug修正,都是需要提交最多三個分支的。研發人員的操作會非常複雜。

但是由於這個流程解決了我們實際生產流程中的問題,所以整體在控制和配合上帶來的收益遠大於我們的障礙。所以這套流程還是長期推廣了起來。

總結

Git是一個工具,Flow是一套管理流程。最重要的並不是我們在用什麼,而是我們解決了什麼問題?我們試圖解決的問題到底是不是真實的問題,還是我們一廂情願臆想出來的。整個過程,實際上是我們針對企業的環境和問題進行發掘的解決的過程,而不是單純挑選工具和流程的過程。
記得先問自己,我現在到底要解決的是什麼問題?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章