GitFlow 代碼版本管理
Git的優點
現在大多數公司的研發團隊都在Git作爲代碼管理工具,使用CVS、SVN等已經很少。至於爲什麼選用git,參考《Git、CVS、SVN比較》。Git主要有以下優點:
- Git是分佈式的,本地庫包含了遠程庫的所有內容;
- Git有優秀的分支模型,利於管理;
- Git由於代碼都在本地,打分支和合並分支方便快速,且代價小。
當然Git的有點還有很多,感興趣的,可以去看一下Git本身的設計,內在的架構體現了很多的優勢,不愧是出資天才程序員Linus (Linux之父) 之手。
GitFlow
雖然有Git這樣優秀的版本管理工具,但是我們面對版本管理的時候,依然有非常大得挑戰,我們都知道大家工作在同一個倉庫上,那麼彼此的代碼協作必然帶來很多問題和挑戰,如下:
- 如何開始一個Feature的開發,而不影響別的Feature?
- 由於很容易創建新分支,分支多瞭如何管理,時間久了,如何知道每個分支是幹什麼的?
- 哪些分支已經合併回了主幹?
- 如何進行Release的管理?開始一個Release的時候如何凍結Feature, 如何在Prepare Release的時候,開發人員可以繼續開發新的功能?
- 線上代碼出Bug了,如何快速修復?而且修復的代碼要包含到開發人員的分支以及下一個Release?
- 大部分開發人員現在使用Git就只是用三個甚至兩個分支,一個是Master, 一個是Develop, 還有一個是基於Develop打得各種分支。這個在小項目規模的時候還勉強可以支撐,因爲很多人做項目就只有一個Release, 但是人員一多,而且項目週期一長就會出現各種問題。
諸如以上問題,代碼需要代碼規範一樣,同樣代碼管理也需要一個清晰的流程和規範,荷蘭程序員Vincent Driessen爲了解決這個問題提出了A Successful Git Branching Model。流程圖如下:
- Gitflow工作流程圍繞項目發佈定義了嚴格的分支模型。儘管它比 Feature Branch Workflow 更復雜一些,但它也爲管理更大規模的項目提供了堅實的框架。
- 與 Feature Branch Workflow 比起來,Gitflow 流程並沒有增加任何新的概念或命令。 其特色在於,它爲不同的分支分配了非常明確的角色,並且定義了使用場景和用法。除了用於功能開發的分支,它還使用獨立的分支進行發佈前的準備、記錄以及後期維護。當然,你還是能充分利用 Feature Branch Workflow 的好處:拉拽請求(Pull Request)、隔離的試驗以及更高效率的合作。
GitFlow常用分支
master
- 主分支, 產品的功能全部實現後, 最終在 master 分支對外發布;
- 該分支爲只讀唯一分支, 只能從其他分支(release/hotfix)合併, 不能在此分支修改;
- 另外所有在 master 分支的推送應該打標籤做記錄, 方便追溯;
- 例如 release 合併到 master, 或 hotfix 合併到 master。
develop
- 主開發分支, 基於 master 分支克隆;
- 包含所有要發佈到下一個 release 的代碼;
- 該分支爲只讀唯一分支, 只能從其他分支合併;
- feature 功能分支完成, 合併到 develop(不推送);
- develop 拉取 release 分支, 提測;
- release/hotfix 分支上線完畢, 合併到 develop 並推送。
feature
- 功能開發分支, 基於 develop 分支克隆, 主要用於新需求新功能的開發;
- 功能開發完畢後合到 develop 分支(未正式上線之前不推送到遠程中央倉庫!!!);
- feature 分支可同時存在多個, 用於團隊中多個功能同時開發 , 屬於臨時分支 , 功能完成後可選刪除。
release
- 測試分支, 基於 feature 分支合併到 develop 之後, 從 develop 分支克隆;
- 主要用於提交給測試人員進行功能測試, 測試過程中發現的 BUG 在本分支進行修復, 修復完成上線後合併到 develop/master 分支並推送(完成功能), 打 Tag
- 屬於臨時分支, 功能上線後可選刪除。
hotfix
- 補丁分支, 基於 master 分支克隆, 主要用於對線上的版本進行 BUG 修復;
- 修復完畢後合併到 develop/master 分支並推送, 打 Tag;
- 屬於臨時分支, 補丁修復上線後可選刪除;
- 所有 hotfix 分支的修改會進入到下一個 release。
工作原理
master分支
master分支爲初始分支, 也是用於記錄歷史的分支, 所有在master分支上的Commit應該Tag。
GitFlow 使用兩個分支來記錄項目開發的歷史, 而不是使用單一的 master 分支。在 Gitflow 流程中,master 只是用於保存官方的發佈歷史,而 develop 分支纔是用於集成各種功能開發的分支。使用版本號爲 master 上的所有提交打標籤(tag)也很方便。事實上, Gitflow 流程就是圍繞這兩個特點鮮明的分支展開的。
Feature 分支
分支名 feature/*
每一個新功能的開發都應該各自使用獨立的分支。 爲了備份或便於團隊之間的合作,這種分支也可以被推送到中央倉庫。 但是,在創建新的功能開發分支時,父分支應該選擇 develop(而不是 master)。 當功能開發完成時,改動的代碼應該被合併(merge)到 develop 分支。功能開發永遠不應該直接牽扯到 master。
Release分支
分支名 release/*
Release分支基於Develop分支創建,打完Release分之後,我們可以在這個Release分支上測試,修改Bug等。同時,其它開發人員可以基於開發新的Feature。 (注意:一旦打了Release分支之後不要從Develop分支上合併新的改動到Release分支)
發佈Release分支時,合併Release到Master和Develop, 同時在Master分支上打個Tag記住Release版本號,然後可以刪除Release分支了。
Hotfix分支
分支名 hotfix/*
hotfix分支是維護分支,基於Master分支創建。發佈後的維護工作或者緊急問題的快速修復也需要使用一個獨立的分支。這是唯一一種可以直接基於 master 創建的分支。一旦問題被修復了,所做的改動應該被合併入 master 和 develop分支(或者用於當前發佈的分支)。在這之後,master 上還要使用更新的版本號打好Tag。
工作主要流程
- 初始化項目爲 gitflow, 默認創建 master 分支, 然後從 master 拉取第一個 develop 分支;
- 從 develop 拉取 feature 分支進行編碼開發(多個開發人員拉取多個 feature 同時進行並行開發, 互不影響);
- feature 分支完成後, 合併到 develop(不推送, feature 功能完成還未提測, 推送後會影響其他功能分支的開發),
合併 feature 到 develop, 可以選擇刪除當前 feature, 也可以不刪除, 但當前 feature 就不可更改了, 必須從 release 分支繼續編碼修改 - 從 develop 拉取 release 分支進行提測, 提測過程中在 release 分支上修改 BUG;
- release 分支上線後, 合併 release 分支到 develop/master 並推送, 合併之後, 可選刪除當前 release 分支, 若不刪除, 則當前 release 不可修改。 線上有問題也必須從 master 拉取 hotfix 分支進行修改;
- 上線之後若發現線上 BUG, 從 master 拉取 hotfix 進行 BUG 修改;
- hotfix 通過測試上線後, 合併 hotfix 分支到 master/develop 並推送, 合併之後, 可選刪除當前 hostfix, 若不刪除, 則當前 hotfix 不可修改, 若補丁未修復, 需要從 master 拉取新的 hotfix 繼續修改;
- 當進行一個 feature 時, 若 develop 分支有變動, 如其他開發人員完成功能並上線, 則需要將完成的功能合併到自己分支上,即合併 develop 到當前 feature 分支;
- 當進行一個 release 分支時, 若 develop 分支有變動, 如其他開發人員完成功能並上線, 則需要將完成的功能合併到自己分支上, 即合併 develop 到當前 release 分支 (!!! 因爲當前 release 分支通過測試後會發佈到線上, 如果不合並最新的 develop 分支, 就會發生丟代碼的情況)。
GitFlow流程命令代碼示例
一般命令代碼
創建develop分支
給默認的 master 配備一個 develop 分支, 一種簡單的做法是:讓一個開發者在本地建立一個空的 develop 分支, 然後把它推送到服務器。develop 分支將包含項目的所有歷史,而 master 會是一個縮減版本。現在,其他開發者應該克隆(clone)中央倉庫,並且爲 develop 創建一個追蹤分支。
git branch develop
git push -u origin develop
開始新Feature開發
當我們開始開發新功能時,我們需要各自建立了自己的分支。注意,在創建分支時,父分支不能選擇 master,而要選擇 develop。
git checkout -b some-feature develop
# Optionally, push branch to origin:
git push -u origin some-feature
# 修改
git status
git add some-file
git commit
完成Feature
當新功能開發完畢時,需要將代碼合併到develop分支,並刪除feature分支。
git pull origin develop
git checkout develop
git merge --no-ff some-feature
git push origin develop
git branch -d some-feature
# If you pushed branch to origin:
git push origin --delete some-feature
開始Relase
當功能開發完成時需要新建一個分支來進行產品代碼發佈的相關工作,這個分支專門用於發佈前的準備,包括一些清理工作、全面的測試、文檔的更新以及任何其他的準備工作。它與用於功能開發的分支相似,不同之處在於它是專爲產品代碼發佈服務的。一旦創建了這個分支並把它推向中央倉庫,這次產品發佈包含的功能也就固定下來了。 任何還處於開發狀態的功能只能等待下一個發佈週期。
git checkout -b release-0.1.0 develop
# Optional: Bump version number, commit
# Prepare release, commit
完成Release
一切準備就緒之後,就要把發佈分支合併入 master 和 develop 分支, 併爲 master 分支打賞合適的標籤,然後再將發佈分支刪除。注意,往 develop 分支的合併是很重要的,因爲開發人員可能在發佈分支上修復了一些關鍵的問題,而這些修復對於正在開發中的新功能是有益的。再次提醒一下,如果 A 功能團隊強調代碼評審(Code Review),此時非常適合提出這樣的請求。
git checkout master
git merge --no-ff release-0.1.0
git push
git checkout develop
git merge --no-ff release-0.1.0
git push
git branch -d release-0.1.0
# If you pushed branch to origin:
git push origin --delete release-0.1.0
git tag -a v0.1.0 master
git push --tags
開始Hotfix
如果線上發現bug,需要從 master 分支新建一個維護分支來修復線上bug。
git checkout -b hotfix-0.1.1 master
完成Hotfix
當bug修復完畢,需要將代碼合併到 master/develop 分支, 並將 master 打上Tag, 最後刪除維護分支。
git checkout master
git merge --no-ff hotfix-0.1.1
git push
git checkout develop
git merge --no-ff hotfix-0.1.1
git push
git branch -d hotfix-0.1.1
git tag -a v0.1.1 master
git push --tags
GitFlow 命令代碼
- 初始化:
git flow init
這個命令會進行一些默認的配置,可以自動創建上面介紹的所有分支:master、develop、feature、relase、hotfix 等分支。 完成後當前所在分支就變成 develop. 任何開發都必須從 develop 開始。 - 開始新 Feature:
git flow feature start MYFEATURE
該命令會創建一個feature分支 - 完成一個 Feature:
git flow feature finish MYFEATURE
該命令將會把 feature/MYFEATURE 合併到 develope 分支,然後刪除功能(feature)分支。 - Publish 一個 Feature(也就是 push 到遠程服務器):
git flow feature publish MYFEATURE
- 獲取 Publish 的 Feature:
git flow feature pull origin MYFEATURE
- 開始一個 Release:
git flow release start RELEASE BASE
- 發佈 Release:
git flow release finish RELEASE
當完成(finish)一個發佈分支時,它會把所有的修改合併到 master 分支,同時合併回 develop 分支,所以不需要擔心 master 分支比 develop 分支更加超前。 - Publish 一個 Release:
git flow release publish RELEASE
- 注意打標籤
git push --tags
- 開始一個 Hotfix:
git flow hotfix start VERSION BASENAME
- 發佈一個 Hotfix:
git flow hotfix finish VERSION
當完成(finish)一個維護分支時,它會把所有的修改合併到 master 分支,同時合併回 develop 分支。