項目中的Git使用規範

項目中的 Git 使用規範

https://jaeger.itscoder.com/ 文章來源,本地記錄防丟失html

介紹

祖師爺 Linus 在創造了偉大的 Linux 以後,又創造了應用最普遍的代碼管理工具 —— Git,極大地提升了程序員的生產力。 現現在大部分項目都在使用 Git 做爲代碼管理工具,不管是在代碼管理、版本控制以及團隊協做上,Git 相比其餘版本控制軟件都有着無可比擬的優點。git

雖然 Git 是個優秀的工具,可是在項目中是否可以正確合理地使用,是否可以發揮其最大的優點,就我本身這幾年的工做經從來看,對於大部分團隊這個問題的答案是否認的。程序員

大部分程序員對 Git 的使用基本上都停留在 git add、git commit、git push、git pull 這幾個指令上,並且大部分團隊也沒有 Git 規範,提交信息充斥着大量的 「fix」、「update」,分支管理也很混亂,代碼提交哪一個分支上也沒具體的規定,致使在團隊協做過程當中常常出現代碼合併後誰的代碼不見了,修過的 bug 在新版本又出現了……github

咱們可能面臨的問題

試想遇到如下這些問題,你會採起怎樣的方式去解決:微信

  • 須要線上某個歷史版本的源碼,直接在 develop 分支根據提交記錄和時間找對應的節點?
  • 線上版本出現嚴重 bug 須要緊急修復發版本,而你的項目就一個分支,上個版本發佈以後已經有大量改動了,怎麼辦?
  • 某個提交改動了部分代碼,涉及到 10 幾個文件,如今這個改動不須要了,此時要一個個找出這些文件而後再改回去麼?
  • 出現了一個 bug,以前好像處理過,可是如今忘了當初怎麼處理的了,在一堆寫着 「fix bug」、「update」 的提交記錄中,如何找到當初那筆的提交?
  • 某個功能原本準備發佈的,如今忽然決定這個版本不上了,如今要一到處找到以前的代碼,而後再改回去?
  • ……

以上這些問題在咱們的項目中都是會或多或少出現的,部分問題可能涉及到的是對 Git 的功能是否熟悉的問題,大部分問題則是涉及到一個項目的 Git 使用規範問題,若是有一個很好的規範,在項目中合理地使用 Git,不少問題壓根就不是問題。工具

Git規範的必要性

既然認同須要一份 Git 規範,那麼這個規範須要規範哪些內容,解決哪些問題,又帶來哪些好處呢?我的認爲有如下幾點:post

  1. 分支管理性能

    • 代碼提交在應該提交的分支
    • 隨時能夠切換到線上穩定版本代碼
    • 多個版本的開發工做同時進行
  2. 提交記錄的可讀性測試

    • 準確的提交描述,具有可檢索性
    • 合理的提交範圍,避免一個功能就一筆提交
    • 分支間的合併保有提交歷史,且合併後結果清晰明瞭
    • 避免出現過多的分叉
  3. 團隊協做插件

    • 明確每一個分支的功用,作到對應的分支執行對應的操做
    • 合理的提交,每次提交有明確的改動範圍和規範的提交信息
    • 使用 Git 管理版本迭代、緊急線上 bug fix、功能開發等任務

以上就是一份 Git 規範的做用和使命。

接下來結合 Git-Flow 和我的實際的項目經驗,總結了一份項目中使用 Git 的規範,其中大部份內容都是對 Git-Flow 進行一個解讀和擴展,告訴你們爲何這麼作以及怎麼作。 這裏也推薦一下 Git-Flow 相關的內容:

A successful Git branching model » nvie.com

這是一份 2010 年提出來的分支管理規範,距今已過去 8 年了,可是其工做流程至今仍是適用的,也衍生出不少優秀的開發流程。

如下就是 Git-Flow 的經典流程圖:

git-flow

若是你熟悉 Git-Flow,那麼你對上圖中的各類分支和線應該都可以理解,若是你以前沒了解過相關的知識,那你可能會有點懵,不過在讀完本文以後再看這張圖,應該就可以理解了。

分支管理規範

1. 分支說明和操做
  • master 分支

    • 主分支,永遠處於穩定狀態,對應當前線上版本
    • 以 tag 標記一個版本,所以在 master 分支上看到的每個 tag 都應該對應一個線上版本
    • 不容許在該分支直接提交代碼
  • develop 分支

    • 開發分支,包含了項目最新的功能和代碼,全部開發都依賴 develop 分支進行
    • 小的改動能夠直接在 develop 分支進行,改動較多時切出新的 feature 分支進行

注: 更好的作法是 develop 分支做爲開發的主分支,也不容許直接提交代碼。小改動也應該以 feature 分支提 merge request 合併,目的是保證每一個改動都通過了強制代碼 review,下降代碼風險

  • feature 分支

    • 功能分支,開發新功能的分支
    • 開發新的功能或者改動較大的調整,從 develop 分支切換出 feature 分支,分支名稱爲 feature/xxx
    • 開發完成後合併回 develop 分支而且刪除該 feature/xxx 分支
  • release 分支

    • 發佈分支,新功能合併到 develop 分支,準備發佈新版本時使用的分支
    • 當 develop 分支完成功能合併和部分 bug fix,準備發佈新版本時,切出一個 release 分支,來作發佈前的準備,分支名約定爲release/xxx
    • 發佈以前發現的 bug 就直接在這個分支上修復,肯定準備發版本就合併到 master 分支,完成發佈,同時合併到 develop 分支
  • hotfix 分支

    • hotfix 分支
    • 當線上版本出現 bug 時,從 master 分支切出一個 hotfix/xxx 分支,完成 bug 修復,而後將 hotfix/xxx 合併到 master 和 develop 分支(若是此時存在 release 分支,則應該合併到 release 分支),合併完成後刪除該 hotfix/xxx 分支

以上就是在項目中應該出現的分支以及每一個分支功能的說明。 其中穩定長期存在的分支只有 master 和 develop 分支,別的分支在完成對應的使命以後都會合併到這兩個分支而後被刪除。簡單總結以下:

  • master 分支: 線上穩定版本分支
  • develop 分支: 開發分支,衍生出 feature 分支和 release 分支
  • release 分支: 發佈分支,準備待發布版本的分支,存在多個,版本發佈以後刪除
  • feature 分支: 功能分支,完成特定功能開發的分支,存在多個,功能合併以後刪除
  • hotfix 分支: 緊急熱修復分支,存在多個,緊急版本發佈以後刪除
2. 分支間操做注意事項

在團隊開發過程當中,避免不了和其餘人一塊兒協做, 同時也會遇到合併分支等一些操做,這裏提交 2 個我的以爲比較好的分支操做規範。

  • 同一分支 git pull 使用 rebase

首先看一張圖:

git-pull-no-rebase

看到這樣的  提交線圖,想從中看出一條清晰的提交線幾乎是不可能的,充滿了 Merge remote-tracking branch 'origin/xxx' into xxx 這樣的提交記錄,同時也將提交線弄成了交錯縱橫的圖,沒有了可讀性。

這裏最大的緣由就是由於默認的 git pull 使用的是 merge 行爲,當你更新代碼時,若是本地存在未推送到遠程的提交,就會產生一個這樣的 merge 提交記錄。所以在同一個分支上更新代碼時推薦使用 git pull --rebase。

下面這張圖展現了默認的 git pull 和 git pull --rebase 的結果差別,使用 git pull --rebase 目的是修整提交線圖,使其造成一條直線。

git-pull-rebase

默認的 git pull 行爲是 merge,能夠進行以下設置修改默認的 git pull 行爲:

# 爲某個分支單獨設置,這裏是設置 dev 分支
    git config branch.dev.rebase true
    # 全局設置,全部的分支 git pull 均使用 --rebase
    git config --global pull.rebase true
    git config --global branch.autoSetupRebase always

這裏須要說明一下,在我看來使用 git pull --rebase 操做是比較好的,可以獲得一條很清晰的提交直線圖,方便查看提交記錄和 code review,可是因爲 rebase 會改變提交歷史,也存在一些很差的影響。這裏就不作過多的討論了,有興趣的話能夠移步知乎上的討論:在開發過程當中使用 git rebase 仍是 git merge,優缺點分別是什麼?

  • 分支合併使用 --no-ff
# 例如當前在 develop 分支,須要合併 feature/xxx 分支
    git merge --no-ff feature/xxx

在解釋這個命令以前,先解釋下 Git 中的 fast-forward: 舉例來講,開發一直在 develop 分支進行,此時有個新功能須要開發,新建一個 feature/a 分支,並在其上進行一系列開發和提交。當完成功能開發時,此時回到 develop 分支,此時 develop 分支在建立 feature/a 分支以後沒有產生任何的 commit,那麼此時的合併就叫作 fast-forward。

fast-forward 合併的結果以下圖所示,這種 merge 的結果就是一條直線了,沒法明確看到切出一個新的 feature 分支,並完成了一個新的功能開發,所以此時比較推薦使用 git merge --no-ff,獲得的結果就很明確知道,新的一系列提交是完成了一個新的功能,若是須要對這個功能進行 code review,那麼只須要檢視叉的那條線上的提交便可。

git_mwrge_diff

關於以上兩個分支間的操做建議,若是須要了解更多,能夠閱讀> 潔癖者用 Git:pull --rebase 和 merge --no-ff 這篇文章。

3. 項目分支操做流程示例

這部份內容結合平常項目的開發流程,涉及到開發新功能、分支合併、發佈新版本以及發佈緊急修復版本等操做,展現經常使用的命令和操做。

3.1. 切到 develop 分支,更新 develop 最新代碼

git checkout develop
git pull --rebase

3.2. 新建 feature 分支,開發新功能

git checkout -b feature/xxx
...
git add <files>
git commit -m "feat(xxx): commit a"
git commit -m "feat(xxx): commit b"
# 其餘提交
...

若是此時 develop 分支有一筆提交,影響到你的 feature 開發,能夠 rebase develop 分支,前提是 該 feature 分支只有你本身一個在開發,若是多人都在該分支,須要進行協調:

# 切換到 develop 分支並更新 develop 分支代碼
git checkout develop
git pull --rebase

# 切回 feature 分支
git checkout feature/xxx
git rebase develop

# 若是須要提交到遠端,且以前已經提交到遠端,此時須要強推(強推需慎重!)
git push --force

上述場景也能夠經過 git cherry-pick 來實現,有興趣的能夠去了解一下這個指令。

3.3. 完成 feature 分支,合併到 develop 分支

# 切到 develop 分支,更新下代碼
git check develop
git pull --rebase

# 合併 feature 分支
git merge feature/xxx --no-ff

# 刪除 feature 分支
git branch -d feature/xxx

# 推到遠端
git push origin develop

3.4. 當某個版本全部的 feature 分支均合併到 develop 分支,就能夠切出 release 分支,準備發佈新版本,提交測試並進行 bug fix

# 當前在 develop 分支
git checkout -b release/xxx

# 在 release/xxx 分支進行 bug fix
git commit -m "fix(xxx): xxxxx"
...

3.5. 全部 bug 修復完成,準備發佈新版本

# master 分支合併 release 分支並添加 tag
git checkout master
git merge --no-ff release/xxx --no-ff
# 添加版本標記,這裏可使用版本發佈日期或者具體的版本號
git tag 1.0.0

# develop 分支合併 release 分支
git checkout develop
git merge --no-ff release/xxx

# 刪除 release 分支
git branch -d release/xxx

至此,一個新版本發佈完成。

3.6. 線上出現 bug,須要緊急發佈修復版本

# 當前在 master 分支
git checkout master

# 切出 hotfix 分支
git checkout -b hotfix/xxx

... 進行 bug fix 提交

# master 分支合併 hotfix 分支並添加 tag(緊急版本)
git checkout master
git merge --no-ff hotfix/xxx --no-ff
# 添加版本標記,這裏可使用版本發佈日期或者具體的版本號
git tag 1.0.1

# develop 分支合併 hotfix 分支(若是此時存在 release 分支的話,應當合併到 release 分支)
git checkout develop
git merge --no-ff hotfix/xxx

# 刪除 hotfix 分支
git branch -d hotfix/xxx

至此,緊急版本發佈完成。

提交信息規範

提交信息規範部分參考 Angular.js commit messgae

git commit 格式 以下:

<type>(<scope>): <subject>

各個部分的說明以下:

  • type 類型,提交的類別

    • feat: 新功能
    • fix: 修復 bug
    • docs: 文檔變更
    • style: 格式調整,對代碼實際運行沒有改動,例如添加空行、格式化等
    • refactor: bug 修復和添加新功能以外的代碼改動
    • perf: 提高性能的改動
    • test: 添加或修正測試代碼
    • chore: 構建過程或輔助工具和庫(如文檔生成)的更改
  • scope 修改範圍

主要是此次修改涉及到的部分,簡單歸納,例如 login、train-order

  • subject 修改的描述

具體的修改描述信息

  • 範例
feat(detail): 詳情頁修改樣式
fix(login): 登陸頁面錯誤處理
test(list): 列表頁添加測試代碼

這裏對提交規範加幾點說明:

  1. type + scope 可以控制每筆提交改動的文件儘量少且集中,避免一次不少文件改動或者多個改動合成一筆。
  2. subject 對於大部分國內項目而已,若是團隊總體英文不是較高水平,比較推薦使用中文,方便閱讀和檢索。
  3. 避免重複的提交信息,若是發現上一筆提交沒改完整,可使用 git commit --amend 指令追加改動,儘可能避免重複的提交信息。

參考資料

相關文章
相關標籤/搜索