分支說(shuō)明和對(duì)應(yīng)的操作
master分支
Git主分支的名字,默認(rèn)叫做master蜀漆。它是自動(dòng)建立的,版本庫(kù)初始化以后咱旱,默認(rèn)就是在主分支在進(jìn)行開發(fā)确丢。
主分支,永遠(yuǎn)處于穩(wěn)定狀態(tài)吐限,對(duì)應(yīng)當(dāng)前線上版本鲜侥。
以tag標(biāo)記一個(gè)版本,因此在master分支上看到的每一個(gè)tag都應(yīng)該對(duì)應(yīng)一個(gè)線上版本诸典。
-
不允許在該分支直接提交代碼描函。
dev分支
開發(fā)分支,包含了項(xiàng)目最新的功能和代碼搂赋,所有開發(fā)都依賴dev分支進(jìn)行赘阀。
可以用來(lái)生成代碼的最新隔夜版本(nightly)益缠。如果想正式對(duì)外發(fā)布脑奠,就在master分支上,對(duì)dev分支進(jìn)行"合并"(merge)幅慌。
小的改動(dòng)可以直接在dev分支進(jìn)行宋欺,改動(dòng)較多時(shí)應(yīng)該切出新的feature分支進(jìn)行。
注:更好的做法是dev分支作為開發(fā)的主分支胰伍,也不允許直接提交代碼齿诞。小改動(dòng)也應(yīng)該以feature分支提merge request合并,目的是保證每個(gè)改動(dòng)都經(jīng)過(guò)了強(qiáng)制代碼review骂租,降低代碼風(fēng)險(xiǎn)祷杈。暫時(shí)不啟用這個(gè)方式。
Git創(chuàng)建dev分支的命令:
git checkout -b dev master
將dev分支發(fā)布到master分支的命令:
# 切換到Master分支
git checkout master
# 對(duì)dev分支進(jìn)行合并
git merge --no-ff dev
--no-ff參數(shù):默認(rèn)情況下渗饮,Git執(zhí)行"快進(jìn)式合并"(fast-farward merge)但汞,會(huì)直接將Master分支指向Develop分支宿刮。
使用--no-ff參數(shù)后,會(huì)執(zhí)行正常合并私蕾,在Master分支上生成一個(gè)新節(jié)點(diǎn)僵缺。
feature分支
功能分支,開發(fā)新功能的分支踩叭。
開發(fā)新的功能或者改動(dòng)較大的調(diào)整磕潮,從develop分支切換出feature分支,分支名稱為feature-xxx容贝。
開發(fā)完成后合并回develop分支并且刪除該feature-xxx分支自脯。
功能分支的名字,可以采用feature-*的形式命名斤富。
創(chuàng)建一個(gè)功能分支:
git checkout -b feature-x dev
開發(fā)完成后冤今,將功能分支合并到dev分支:
git checkout dev
git merge --no-ff feature-xxx
刪除feature分支:
git branch -d feature-xxx
release分支
發(fā)布分支,新功能合并到dev分支茂缚,準(zhǔn)備發(fā)布新版本時(shí)使用的分支戏罢。預(yù)發(fā)布分支是從dev分支上面分出來(lái)的,預(yù)發(fā)布結(jié)束以后脚囊,必須合并進(jìn)dev和master分支龟糕。
當(dāng)dev分支完成功能合并和部分bug fix,準(zhǔn)備發(fā)布新版本時(shí)悔耘,切出一個(gè)release分支讲岁,來(lái)做發(fā)布前的準(zhǔn)備,分支名約定為release-*衬以。
發(fā)布之前發(fā)現(xiàn)的bug就直接在這個(gè)分支上修復(fù)缓艳,確定準(zhǔn)備發(fā)版本就合并到master分支,完成發(fā)布看峻,同時(shí)合并到dev分支阶淘。
創(chuàng)建一個(gè)預(yù)發(fā)布分支:
git checkout -b release-1.2 dev
確認(rèn)沒有問題后,合并到master分支:
git checkout master
git merge --no-ff release-1.2
# 對(duì)合并生成的新節(jié)點(diǎn)互妓,做一個(gè)標(biāo)簽
git tag -a 1.2
再合并到dev分支:
git checkout dev
git merge --no-ff release-1.2
最后溪窒,刪除預(yù)發(fā)布分支:
git branch -d release-1.2
fixbug分支,緊急修復(fù)bug分支
緊急修復(fù)線上bug分支
當(dāng)線上版本出現(xiàn)bug時(shí)冯勉,從master分支切出一個(gè)fixbug-分支澈蚌,完成bug修復(fù),然后將fixbug-合并到master和dev分支(如果此時(shí)存在release分支灼狰,則應(yīng)該合并到release分支)宛瞄,合并完成后刪除該fixbug-*分支。
注意:以上就是在項(xiàng)目中應(yīng)該出現(xiàn)的分支以及每個(gè)分支功能的說(shuō)明交胚。其中穩(wěn)定長(zhǎng)期存在的分支只有master和dev分支份汗,別的分支在完成對(duì)應(yīng)的使命之后都會(huì)合并到這兩個(gè)分支然后被刪除伐厌。
創(chuàng)建一個(gè)修補(bǔ)bug分支:
git checkout -b fixbug-0.1 master
修補(bǔ)結(jié)束后,合并到master分支:
git checkout master
git merge --no-ff fixbug-0.1
git tag -a 0.1.1
再合并到develop分支:
git checkout develop
git merge --no-ff fixbug-0.1
最后裸影,刪除"修補(bǔ)bug分支":
git branch -d fixbug-0.1
總結(jié):
- master: 線上穩(wěn)定版本分支挣轨。
- dev: 開發(fā)分支,衍生出feature分支和release分支轩猩。
- release: 發(fā)布分支卷扮,準(zhǔn)備待發(fā)布版本的分支,存在多個(gè)均践,版本發(fā)布之后刪除晤锹。
- feature: 功能分支,完成特定功能開發(fā)的分支彤委,存在多個(gè)鞭铆,功能合并之后刪除。
- fixbug: 緊急熱修復(fù)分支焦影,存在多個(gè)车遂,緊急版本發(fā)布之后刪除。
項(xiàng)目中分支操作流程示例
1斯辰、切到dev分支舶担,更新dev最新代碼。
git checkout develop
git pull --rebase
2彬呻、新建feature分支衣陶,開發(fā)新功能
git checkout -b feature-xxx
git add <files>
git commit -m "feat(xxx): commit a"
git commit -m "feat(xxx): commit b"
# 其他提交
如果此時(shí)dev分支有一筆提交,影響到你的feature開發(fā)闸氮,可以rebase dev分支剪况,前提是該feature分支只有你自己一個(gè)在開發(fā),如果多人都在該分支蒲跨,需要進(jìn)行協(xié)調(diào):
# 切換到dev分支并更新dev分支代碼
git checkout dev
git pull --rebase
# 切回 feature 分支
git checkout feature-xxx
git rebase develop
# 如果需要提交到遠(yuǎn)端译断,且之前已經(jīng)提交到遠(yuǎn)端,此時(shí)需要強(qiáng)推(強(qiáng)推需慎重财骨!)
git push --force
3镐作、完成feature分支,合并到dev分支
# 切到dev分支隆箩,更新下代碼
git check dev
git pull --rebase
# 合并feature分支
git merge feature-xxx --no-ff
# 刪除feature分支
git branch -d feature-xxx
# 推到遠(yuǎn)端
git push origin dev
4、當(dāng)某個(gè)版本所有的feature分支均合并到dev分支羔杨,就可以切出release分支捌臊,準(zhǔn)備發(fā)布新版本,提交測(cè)試并進(jìn)行bug fix
# 當(dāng)前在dev分支
git checkout -b release-xxx
# 在 release-xxx 分支進(jìn)行 bug fix
git commit -m "fix(xxx): xxxxx"
5兜材、所有 bug 修復(fù)完成理澎,準(zhǔn)備發(fā)布新版本
# master分支合并release分支并添加tag
git checkout master
git merge --no-ff release-xxx --no-ff
# 添加版本標(biāo)記逞力,這里可以使用版本發(fā)布日期或者具體的版本號(hào)
git tag 1.0.0
# dev分支合并release分支
git checkout dev
git merge --no-ff release/xxx
# 刪除 release 分支
git branch -d release/xxx
至此,一個(gè)新版本發(fā)布完成糠爬。
6寇荧、線上出現(xiàn) bug,需要緊急發(fā)布修復(fù)版本
# 當(dāng)前在master分支
git checkout master
# 切出fixbug分支
git checkout -b fixbug-xxx
... 進(jìn)行bug fix提交
# master分支合并fixbug分支并添加tag(緊急版本)
git checkout master
git merge --no-ff hotfix/xxx --no-ff
# 添加版本標(biāo)記执隧,這里可以使用版本發(fā)布日期或者具體的版本號(hào)
git tag 1.0.1
# dev分支合并fixbug分支(如果此時(shí)存在release分支的話揩抡,應(yīng)當(dāng)合并到release分支)
git checkout develop
git merge --no-ff fixbug-xxx
# 刪除fixbug分支
git branch -d hotfix-xxx
至此,緊急版本發(fā)布完成镀琉。
提交信息規(guī)范
git commit 格式如下:
<type>(<scope>): <subject>
具體格式:
<type>: <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
type: 本次commit的類型峦嗤,諸如bugfix docs style等
scope: 本次 commit 波及的范圍
subject: 簡(jiǎn)明扼要的闡述下本次 commit 的主旨,1.使用祈使句屋摔;2.首字母不要大寫烁设;3.結(jié)尾無(wú)需添加標(biāo)點(diǎn);
body: 同樣使用祈使句钓试,在主體內(nèi)容中我們需要把本次commit詳細(xì)的描述一下装黑,比如此次變更的動(dòng)機(jī),如需換行弓熏,則使用 |
footer: 描述下與之關(guān)聯(lián)的issue或break change
各個(gè)部分的說(shuō)明如下:
- type 類型曹体,提交的類別
- feat: 新功能
- fix: 修復(fù) bug
- docs: 文檔變動(dòng)
- style: 格式調(diào)整,對(duì)代碼實(shí)際運(yùn)行沒有改動(dòng)硝烂,例如添加空行箕别、格式化等
- refactor: bug 修復(fù)和添加新功能之外的代碼改動(dòng)
- perf: 提升性能的改動(dòng)
- test: 添加或修正測(cè)試代碼
- chore: 構(gòu)建過(guò)程或輔助工具和庫(kù)(如文檔生成)的更改
- scope 修改范圍
- 主要是這次修改涉及到的部分,簡(jiǎn)單概括滞谢,例如 login串稀、iap、search
- subject 修改的描述
- 具體的修改描述信息
Commit messages格式要求
# 標(biāo)題行:50個(gè)字符以內(nèi)狮杨,描述主要變更內(nèi)容
#
# 主體內(nèi)容:更詳細(xì)的說(shuō)明文本母截,建議72個(gè)字符以內(nèi)。 需要描述的信息包括:
#
# * 為什么這個(gè)變更是必須的? 它可能是用來(lái)修復(fù)一個(gè)bug橄教,增加一個(gè)feature清寇,提升性能、可靠性护蝶、穩(wěn)定性等等
# * 他如何解決這個(gè)問題? 具體描述解決問題的步驟
# * 是否存在副作用华烟、風(fēng)險(xiǎn)?
#
# 如果需要的化可以添加一個(gè)鏈接到issue地址或者其它文檔
范例:
feat(home): 首頁(yè)新功能
fix(login): 登錄錯(cuò)誤處理
test(search): 搜索邏輯添加測(cè)試代碼
提交信息規(guī)范說(shuō)明:
type + scope 能夠控制每筆提交改動(dòng)的文件盡可能少且集中,避免一次很多文件改動(dòng)或者多個(gè)改動(dòng)合成一筆持灰。
subject 使用中文盔夜,方便檢索和閱讀。
避免重復(fù)的提交信息,如果發(fā)現(xiàn)上一筆提交沒改完整喂链,可以使用 git commit --amend 指令追加改動(dòng)返十,盡量避免重復(fù)的提交信息。
分支之間操作的注意事項(xiàng)
- 同一分支git pull使用rebase
首先看一張圖:
想從中看出一條清晰的提交線幾乎是不可能的椭微,充滿了 Merge remote-tracking branch 'origin/xxx' into xxx 這樣的提交記錄洞坑,同時(shí)也將提交線弄成了交錯(cuò)縱橫的圖,沒有了可讀性蝇率。
這里最大的原因就是因?yàn)槟J(rèn)的 git pull 使用的是 merge 行為迟杂,當(dāng)你更新代碼時(shí),如果本地存在未推送到遠(yuǎn)程的提交瓢剿,就會(huì)產(chǎn)生一個(gè)這樣的 merge 提交記錄逢慌。因此在同一個(gè)分支上更新代碼時(shí)推薦使用 git pull --rebase。
下面這張圖展示了默認(rèn)的 git pull 和 git pull --rebase 的結(jié)果差異间狂,使用 git pull --rebase 目的是修整提交線圖攻泼,使其形成一條直線。
默認(rèn)的 git pull 行為是 merge鉴象,可以進(jìn)行如下設(shè)置修改默認(rèn)的 git pull 行為:
# 為某個(gè)分支單獨(dú)設(shè)置忙菠,這里是設(shè)置 dev 分支
git config branch.dev.rebase true
# 全局設(shè)置,所有的分支 git pull 均使用 --rebase
git config --global pull.rebase true
git config --global branch.autoSetupRebase always
使用 git pull --rebase 操作是比較好的纺弊,能夠得到一條很清晰的提交直線圖牛欢,方便查看提交記錄和 code review,但是由于 rebase 會(huì)改變提交歷史淆游,也存在一些不好的影響傍睹。
- 分支合并使用 --no-ff
# 例如當(dāng)前在 develop 分支,需要合并 feature/xxx 分支
git merge --no-ff feature/xxx
--no-ff feature 含義:
先解釋下Git中的fast-forward:舉例來(lái)說(shuō)犹菱,開發(fā)一直在dev分支進(jìn)行拾稳,此時(shí)有個(gè)新功能需要開發(fā),新建一個(gè)feature-a分支腊脱,并在其上進(jìn)行一系列開發(fā)和提交访得。
當(dāng)完成功能開發(fā)時(shí),此時(shí)回到dev分支陕凹,此時(shí)develop分支在創(chuàng)建feature-a分支之后沒有產(chǎn)生任何的commit悍抑,那么此時(shí)的合并就叫做fast-forward。
fast-forward 合并的結(jié)果如下圖所示:
這種merge的結(jié)果就是一條直線了杜耙,無(wú)法明確看到切出一個(gè)新的feature分支搜骡,并完成了一個(gè)新的功能開發(fā)。
因此此時(shí)比較推薦使用git merge --no-ff泥技,得到的結(jié)果就很明確知道浆兰,新的一系列提交是完成了一個(gè)新的功能磕仅,如果需要對(duì)這個(gè)功能進(jìn)行code review珊豹,那么只需要檢視叉的那條線上的提交即可簸呈。