Git 分支模型與開發規範

GitHub Flow & Git Flow 基於Git 的兩種協做開發模式html

0一、分支模型

devprocess.png

  • master:長期分支,通常用於管理對外發布版本,每一個 commit 對一個 tag,也就是一個發佈版本
  • develop:長期分支,通常用於做爲平常開發彙總,即開發版的代碼
  • feature: 短時間分支,通常用於一個新功能的開發
  • hotfix :短時間分支 ,通常用於正式發佈之後,出現 bug,須要建立一個分支,進行 bug 修補。
  • release :短時間分支,通常用於發佈正式版本以前(即合併到 master 分支以前),須要有的預發佈的版本進行測試。

master和develop做爲主要分支。git

新功能的開發在feature上進行,該分支從develop分支派生,功能開發完畢後merge到develop分支。 通常feature分支都存在與開發者本地,除非該分支須要多方合做才提交到遠程倉庫。安全

如何保證和develop分支的代碼同步?天天從develop分支拉去最新的代碼,使用rebase命令 不要使用pull,每次合併上游更改時feature 分支都會引入一個外來的合併提交,使用pull會生成一個新的合併commit。app

在將其餘分支的代碼合併到當前分支時,若是那個分支是當前分支的父分支,爲了保持圖表的可讀性和可追蹤性,能夠考慮用 git rebase 來代替 git merge;反過來或者不是父子關係的兩個分支以及互相已經 git merge 過的分支,就不要採用 git rebase 了,避免出現重複的衝突和提交節點。工具

release分支是從develop分支派生, bug fix只在release分支上進行,該分支也是QA的測試分支,開發結束後同時合併進develop和master分支post

使用merge request將release分支的提交合並master分支,並打上tag。測試

hotfix能夠單獨出一個分支,也能夠直接在release分支上進行。spa

全部master上的代碼都是從release分支合併進去的。code

追蹤遠程develop分支

git checkout -b develop origin/develop

 

feature 分支操做

獲取dev分支最新代碼htm

$ git pull --rebase origin dev
或者
$ git rebase dev

$ git checkout -b myfeature develop

$ git checkout develop
Switched to branch 'develop'

$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)

$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).

$ git push origin develop

 

rebase最大的好處是你的項目歷史會很是整潔。首先,它不像git merge 那樣引入沒必要要的合併提交。其次,如上圖所示,rebase致使最後的項目歷史呈現出完美的線性——你能夠從項目終點到起點瀏覽而不須要任何的Fork。這讓你更容易使用git log 、git bisect 和gitk 來查看項目歷史。 不過,這種簡單的提交歷史會帶來兩個後果:安全性和可跟蹤性。若是你違反了Rebase黃金法則,重寫項目歷史可能會給你的協做工做流帶來災難性的影響。此外,rebase不會有合併提交中附帶的信息——你看不到feature分支中併入了上游的哪些更改。

rebase的黃金法則
git rebase 的黃金法則即是,毫不要在公共的分支上使用它。 好比說,若是你把master分支rebase到你的feature分支上會發生什麼

 

場景:你在feature上開發了一些功能尚未可以提交,如今有個Bug須要在develop分支上fix,怎麼操做?

在feature分支上 執行 add & stash ,將當前的更新暫存起來

切換到develop分支,fix bug,commit & push(也能夠不push)

切換到feature分支,rebase develop分支,發現衝突就解決衝突

最後 git stash pop ,彈出以前暫存的內容,這時也可能發生衝突,也比較好解決

這裏主要就是應用了stash的功能,防止在feature上開發的功能還未可以提交,同時又有緊急的bug須要fix。

 

release 分支操做

# 合併到master
$ git checkout master
Switched to branch 'master'

$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

$ git tag -a 1.2

# 合併到develop
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2

# 刪除release分支
$ git branch -d release-1.2

 

hotfix 分支操做

當產品發佈出去以後,有緊急的bug,就須要從master分支中拉出一個hot fix分支。 這麼作的好處是develop分支上的同事能夠繼續進行開發,另外一個團隊則能夠在master分支上進行一個產品修復更新。 修復好以後,合併到mater分支和develop分支。

這裏有一個特殊狀況,若是當時的release分支還存在,那麼hotfix的更新須要merge到相應的release分支上。 若是release分支已經不存在了,那麼就只須要merge到master分支和develop分支。

建立遠程分支

git push origin local_branch:remote_branch
local_branch必須爲你本地存在的分支,remote_branch爲遠程分支,若是remote_branch不存在則會自動建立分支。

 

0二、開發規範

commit規範

只要堅持作到如下幾點就 OK 了:

  1. 提交時的粒度是一個小功能點或者一個 bug fix,這樣進行恢復等的操做時可以將「誤傷」減到最低;
  2. 用一句簡練的話寫在第一行,而後空一行稍微詳細闡述該提交所增長或修改的地方;
  3. 不要每提交一次就推送一次,多積攢幾個提交後一次性推送,這樣能夠避免在進行一次提交後發現代碼中還有小錯誤。

誰說歷史不可篡改了?前提是,想要合併的那幾回提交尚未推送到遠程!

Commit Message 格式

<type>(<scope>): <subject> <空行> <body> <空行> <footer>

type

  • feat:新功能(feature)
  • fix:修補bug
  • docs:文檔(documentation)
  • style: 格式(不影響代碼運行的變更)
  • refactor:重構(即不是新增功能,也不是修改bug的代碼變更)
  • test:增長測試
  • chore:構建過程或輔助工具的變更

Scope
用來講明本次Commit影響的範圍,即簡要說明修改會涉及的部分。這個原本是選填項,但從AngularJS實際項目中能夠看出基本上也成了必填項了。

Subject

用來簡要描述本次改動,概述就行了,由於後面還會在Body裏給出具體信息。而且最好遵循下面三條:

  • 以動詞開頭,使用第一人稱如今時,好比change,而不是changed或changes
  • 首字母不要大寫
  • 結尾不用句號(.)

Body

<body>裏的內容是對上面subject裏內容的展開,在此作更加詳盡的描述,內容裏應該包含修改動機和修改先後的對比。

Footer

footer裏的主要放置不兼容變動和Issue關閉的信息

Revert

此外若是須要撤銷以前的Commit,那麼本次Commit Message中必須以revert:開頭,後面緊跟前面描述的Header部分,格式不變。而且,Body部分的格式也是固定的,必需要記錄撤銷前Commit的SHA值。

 

提交

在具體開發工做中主要須要遵照的原則就是「使每次提交都有質量」,只要堅持作到如下幾點就 OK 了:
1. 提交時的粒度是一個小功能點或者一個 bug fix,這樣進行恢復等的操做時可以將「誤傷」減到最低;
2. 用一句簡練的話寫在第一行,而後空一行稍微詳細闡述該提交所增長或修改的地方;
3. 不要每提交一次就推送一次,多積攢幾個提交後一次性推送,這樣能夠避免在進行一次提交後發現代碼中還有小錯誤。
 
假如已經把代碼提交了,對此次提交的內容進行檢查時發現裏面有個變量單詞拼錯了或者其餘失誤,只要尚未推送到遠程,就有一個不被他人發覺你的疏忽的補救方法——
使用 git rebase -i [SHA] , 具體參考,link
 

推送

當本身一我的進行開發時,在功能完成以前不要急着建立遠程分支。
 

拉取

git pull --rebase
1. 把本地repo從上次pull以後的變動暫存起來
2. 恢復到上次pull時的狀況
3. 套用遠端的變動
4. 最後再套用剛暫存下來的本地變動
 
有衝突怎麼辦?
rebase跟merge相似,出現conflict會暫停rebase動做,須要你手動修復後,而後才能夠繼續動做。這也是rebase比merge複雜一點的地方:merge若是發生conflict,你只須要解決衝突一次,而後commit出去就完成了。而rebase的conflict可能會發生在上述步驟4的每一次從新套用上,因此可能須要解決衝突好幾回。
 
到底何時用merge?何時用rebase?
若是你修改比較多,預期會有較多的conflict,建議用merge。(不過,若是是屢次大範圍的主題式修改,那是否是應該一開始就多開一個branch來作呢?)。
若是改動範圍較小,不太預期有conflict,則建議能夠加上rebase參數。
 
若是想要把 rebase 當作 git pull 的預設值,能夠在專案的 .git/config 加上
[branch "master"]
remote = origin
merge = refs/heads/master
rebase = true
 
也能夠直接加到 ~/.gitconfig 讓全部的 tracked branches 都自動套用這個設定:
[branch]
autosetuprebase = always
 

合併

在將其餘分支的代碼合併到當前分支時,若是那個分支是當前分支的父分支,爲了保持圖表的可讀性和可追蹤性,能夠考慮用 git rebase 來代替 git merge;反過來或者不是父子關係的兩個分支以及互相已經 git merge 過的分支,就不要採用 git rebase 了,避免出現重複的衝突和提交節點。

分支命名

除了主要分支的名字是固定的以外,派生分支是須要本身命名的,這裏就要有個命名規範了。強烈推薦用以下形式:
feature——按照功能點(而不是需求)命名;
release——用發佈時間命名,能夠加上適當的前綴;
hotfix——GitLab 的 issue 編號或 bug 性質等。

另外還有 tag,用語義化的版本號命名。

 

0三、連接

相關文章
相關標籤/搜索