前言
已經使用git flow的開發人員,可以對git開發的頭腦更佳清晰。對未使用git流,或者使用git不久的新人,可以極簡單的理解分支流以及這麼做的原因。
常見(好用)的分支體系
- master 線上版本
- master-B 預發佈版本
- dev 測試版本
- f1,f2,f3功能分支
整個開發流呈現:
當發起一個新功能,從master中拉取出一個分支f4,在f4中完成功能,合併進dev測試,無恙後合併進master-B,讓測試/玩家在預發佈版本中體驗,最後再進入master。
Git流大概是:
# 切換到master
git checkout master
## 新建功能4分支
git branch f4
## 切換到f4
git checkout f4
# f4開發和完成,檢查master是否有更新,有則merge到f4中,f4推送到遠程倉庫
## git add .
## git commit -m "完成f4功能"
## git checkout master
## git pull origin master
## git checkout f4
## git merge master
## git push origin f4
# 合併f4進dev,併發布測試
## 在遠程倉庫中,pull request(f4 ---> dev),完成dev更新f4功能
## 在遠程倉庫中,pull request(f4 ---> master-B),完成master-b更新f4
##............................................(f4 ---> master), 完成master更新f4
這裏不對原理過度解析,而是針對以下問題來解釋爲什麼這樣做?
1. 爲什麼不直接在dev上完成開發?
git流的原則是,只操作屬於你的分支,換句話說,不論是master,master-B還是dev,你擁有的都是隻讀的權限,只有f4是你可以動的。爲什麼不直接在dev上完成開發:
- 因爲可能同時開發n個功能,你和其他人同時開發dev,容易造成衝突。
- 因爲dev上可能有一些未發佈/未測試完的功能,假設你在dev上完成了f4,那麼,你無法做到,從dev合併到master-B時,僅合併f4功能,而不合並未完成的f5功能。
2. 爲什麼完成f4後,要重新切換回master pull一下?
當你從master新建f4分支後,在你完成f4開發過程中,可能master有f5,f6功能合併併發布了。如果你在提交f4時,不重新merge一下master,在線上的pull request上,很大概率會出現合併衝突。
3. 爲什麼不是嚴格地dev --> master, 而是f4 --> master?
除非每個功能都串聯開發,不然就會和問題1的第二個原因一樣,無法在合併時,從dev中僅合併f4進master。
4. master-B預發佈分支的必要性。
不是必要的,視情況而定。
下面,發一個各個分支的日常狀態,或許你可以從中體會一些.
分支狀態
假定數字示功能點,比如:
master: 1, 2 ,3
描述master分支,已完成功能1,功能2,功能3.
狀態分析
master: 1, 2, 3, 16
master-B: 1, 2, 3, 4, 5 ,6, 15, 16
dev: 1, 2, 3 ,4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16
f1: 1, 2, 3 , 12
f2: 1, 2, 3, 13, 16
f3: 1, 2, 3, 14
f4: 1, 2, 3,15
f5: 1, 2, 3 16
描述:
- f1 剛剛從master(1,2,3) 誕生,正在開發12功能,並且未完成,開發過程中,master有功能16合併,但是f1分支還未merge master。
- f2從master(1,2,3)誕生,開發13功能,未完成,對master的16功能已經進行了merge。
- f3從master(1,2,3)誕生,開發完成了f14,並且正在dev裏進行測試,未(預)發佈,因爲f3在提交時,未merge master,就算f3在dev裏測試成功了,在pr進master時,也有可能因爲功能16而造成衝突。
- f4 完成了15功能,發佈進了dev測試,並且進入了預發佈master-B,pr進master時可能因爲16發生衝突。
- f5 完成了16功能,並且先於f1,f2,f3,f4進行了迭代發佈。f5不僅可以代表開發最快的功能,也能代表一些緊急的bug fix。
處理衝突
-
哪個功能出現衝突,哪個功能分支的所有者處理衝突。f4 —> dev 出現衝突,f4功能者處理,而不是dev管理員處理。
-
子功能者保持在master,master-B,dev只讀的情況下進行合併衝突。本地pull master/dev/master-B,merge進f1,再讓f1重新走上述開發流。
-
如果說,有一些功能,只能以git push -f 的方式合併,那一定是某一個開發者,以錯誤的方式操作了分支,比如直接基於dev開發了。
-
如果f1在重新走流程時,又有功能發佈進了master怎麼辦?
不怎麼辦,不管是對master的bug fix還是新功能f2的開發,很大概率對f1的合併都不會造成衝突(僅需要對小概率的合併衝突處理)。 -
如果衝突很頻繁,應該從以下層面考慮和優化:
項目架構,目錄層級,代碼層面上架構比較爛,導致不同功能開發經常出現共享文件、目錄的修改,開發人員應該適當地優化項目目錄的架構,而不是從分支入手。