良好的Commit Message有利於代碼審查,能更快速查找變動記錄,而且能夠直接生成Change log。html
Commit Message的寫法規範:conventional-changelog 爲了規範代碼提交的說明,這裏咱們使用angular的規範寫法:前端
<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>
複製代碼
其中 head((): )是必須的,body和footer是可選的。 若是隻須要輸入header,能夠直接使用:java
git commit -m
複製代碼
命令提交。linux
若是須要輸入body、footer這樣的多行日誌,須要輸入:git
git commit
複製代碼
跳出文本編輯器進行編寫。github
commit的類別,包涵如下七種:shell
feat:新功能(feature)
fix:修補bug
docs:文檔(documentation)
style: 格式(不影響代碼運行的變更)
refactor:重構(即不是新增功能,也不是修改bug的代碼變更)
test:增長測試
chore:構建過程或輔助工具的變更
複製代碼
commit的影響範圍,好比會影響到哪一個模塊/性能/哪一層(業務層,持久層,緩存,rpc),若是是特性代碼,能夠寫特性名稱express
commit的簡短描述,不超過50個字符。npm
跟subject同樣,使用如今式,祈使句。應該說明提交代碼的動機,以及跟前一個版本的對比。segmentfault
Foot包含能夠包含如下信息:
以 BREAKING CHANGE 開頭,後面是變動的具體描述,如
BREAKING CHANGE: isolate scope bindings definition has changed and
the inject option for the directive controller injection was removed.
To migrate the code follow the example below:
Before:
scope: {
myAttr: 'attribute',
myBind: 'bind',
myExpression: 'expression',
myEval: 'evaluate',
myAccessor: 'accessor'
}
After:
scope: {
myAttr: '@',
myBind: '@',
myExpression: '&',
// myEval - usually not useful, but in cases where the expression is assignable, you can use '='
myAccessor: '=' // in directive's template change myAccessor() to myAccessor } The removed `inject` wasn't generaly useful for directives so there should be no code using it.
複製代碼
如:
Closes DB-1001, DB1002
複製代碼
feat($browser): onUrlChange event (popstate/hashchange/polling)
Added new event to $browser:
- forward popstate event if available
- forward hashchange event if popstate not available
- do polling when neither popstate nor hashchange available
Breaks $browser.onHashChange, which was removed (use onUrlChange instead)
---------
fix($compile): couple of unit tests for IE9
Older IEs serialize html uppercased, but IE9 does not...
Would be better to expect case insensitive, unfortunately jasmine does
not allow to user regexps for throw expectations.
Closes #392
Breaks foo.bar api, foo.baz should be used instead
---------
eat(directive): ng:disabled, ng:checked, ng:multiple, ng:readonly, ng:selected
New directives for proper binding these attributes in older browsers (IE).
Added coresponding description, live examples and e2e tests.
Closes #351
---------
feat($compile): simplify isolate scope bindings
Changed the isolate scope binding options to:
- @attr - attribute binding (including interpolation)
- =model - by-directional model binding
- &expr - expression execution binding
This change simplifies the terminology as well as
number of choices available to the developer. It
also supports local name aliasing from the parent.
BREAKING CHANGE: isolate scope bindings definition has changed and
the inject option for the directive controller injection was removed.
To migrate the code follow the example below:
Before:
scope: {
myAttr: 'attribute',
myBind: 'bind',
myExpression: 'expression',
myEval: 'evaluate',
myAccessor: 'accessor'
}
After:
scope: {
myAttr: '@',
myBind: '@',
myExpression: '&',
// myEval - usually not useful, but in cases where the expression is assignable, you can use '='
myAccessor: '=' // in directive's template change myAccessor() to myAccessor } The removed `inject` wasn't generaly useful for directives so there should be no code using it.
複製代碼
若是是特性開發,則能夠這樣:
feat(短視頻播放優化): 全屏播放動畫效果優化
複製代碼
在NodeJS項目中,咱們能夠經過使用 ghooks + validate-commit-msg進行提交日誌校驗,校驗不經過的將被拒絕提交。原理是經過NodeJs項目編譯,把NodeJS的校驗腳本寫到.git/hooks/
目錄下的勾子文件中,這樣每次執行git commit
命令都會執行這個校驗,不過這種方式依賴於Node環境,而且每一個Git項目都須要引入對應的npm模塊進行編譯,對於比較多微服務項目的狀況來講使用不太方便。
爲此,編寫了git-hook-maven-plugin插件, 該插件有以下特色:
Maven
的生命週期中的某個階段, 方便的經過項目編譯自動安裝或者升級腳本;validate-commit-message
鉤子腳本, 用於提交日誌的規範, 遵循AngularJS Git Commit Message Conventions的格式。配置完這個,當咱們經過maven編譯完項目以後,下一次提交代碼,若是提交日誌不符合規範,則會報錯:
➜ project-1 git:(master) ✗ git commit -m "test"
Commit log error: First commit message line (commit header) does not follow format: type(scope): subject
- Refer commit guide: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
複製代碼
對於獨自完成的特性,可能在開發過程當中會產生多個提交,爲了讓提交整潔,須要對這個特性的全部提交進行壓縮合並。咱們先看看壓縮合並以前的代碼:
* be6e32d (HEAD->master)feat(測試提交): 修改第二個文件
* 4a7615e feat(測試提交): 修改第一個文件
* 721064e feat(測試提交): 提交第四個文件
* e20968e feat(測試提交): 提交第三個文件
* b7160b3 feat(測試提交): 提交第二個文件
* 0c90fcl feat(測試提交): 提交第一個文件
* e618321 fix(頁面展現): 展現錯誤修復
複製代碼
如圖,能夠發現壓縮合並測試
特性有多個提交,能夠進行合併,如今準備把e618321
前面的提交都進行合併,執行git rebase -i
命令進行壓縮合並:
git rebase -i e618321
其中命令後面的hash值是壓縮合並開始的那個提交的hash值:
pick 0c90fcl feat (測試提交): 提交第一個文件
pick b7160b3 feat(測試提交): 提交第二個文件
pick e20968e feat(測試提交): 提交第三個文件
pick 721064e feat(測試提交): 提交第四個文件
pick 4a7615e feat(測試提交): 修改第一個文件
pick be6e32d feat(測試提交): 修改第二個文件
# Rebase e618321..be6e32d onto e618321 (6 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
複製代碼
注意:這個界面裏面的提交是按照提交時間順序往下排的,最新提交的在最後面,跟git lg
的相反,平時查看日誌是最新提交的排在最前面。
咱們把低2行到6行改成 s(squash),第一個行改成 r(reword),把第2到6行合併到第一個提交裏面,調整下提交信息:
r 0c90fcl feat (測試提交): 提交第一個文件
s b7160b3 feat(測試提交): 提交第二個文件
s e20968e feat(測試提交): 提交第三個文件
s 721064e feat(測試提交): 提交第四個文件
s 4a7615e feat(測試提交): 修改第一個文件
s be6e32d feat(測試提交): 修改第二個文件
複製代碼
而後輸 :wq 保存並退出編輯模式繼續處理。
若是遇到有衝突,須要解決完衝突以後,修改衝突的提交日誌。
最後是一個壓縮合並以後的提交日誌確認界面,看看第一行的日誌是否符合咱們的需求,沒有問題則輸入 :wq 保存並退出編輯模式。
# This is acombination of 7commits.
# The first commit'smessage is:
feat(測試提交): 測試代碼
# This is the 2nd commit message:
feat(測試提交): 提交第二個文件
# This is the 3rd commit message:
feat(測試提交): 提交第三個文件
複製代碼
這樣咱們就合併完成了,再次查看提交日誌,發現已經合併程了一個提交:
* eb0121a (HEAD->master) feat(測試提交): 測試代碼
* e618321 fix(頁面展現): 展現錯誤修復
複製代碼
注:git lg中 lg = log --graph --oneline --decorate,特別注意,本次演示代碼直接在master上面進行,實際上須要在 feature-xxx 分支上面進行。
提交代碼和壓縮合並的原則:
開發過程當中的提交代碼原則: 儘可能減小commit的次數; 在push以前,須要把本次特性全部的代碼都壓縮成一個提交; 在提交代碼審查以前,最好把本次特產壓縮成一個提交
假設咱們開發一個新的特性,而且已經把代碼進行了壓縮合並,提交日誌以下:
* 69b4ffb (HEAD -> feature-test) feat(測試特性): 測試特性代碼
* eb0121a (HEAD->master) feat(測試提交): 測試代碼
* e618321 fix(頁面展現): 展現錯誤修復
複製代碼
而此時,master代碼也有了新的修復代碼提交:
* 69b4ffb (HEAD -> master) fix(緩存): 修復產品接口緩存bug
* eb0121a (HEAD->master) feat(測試提交): 測試代碼
* e618321 fix(頁面展現): 展現錯誤修復
複製代碼
爲了保持合併以後,咱們當前特性點仍然在提交日誌的最新位置,達成效果以下:
咱們使用rebase
進行合併代碼:
git rebase master
合併以後效果以下,咱們當前特性分支的提交仍然在最前面:
* 69b4ffb (HEAD -> feature-test) feat(測試特性): 測試特性代碼
* 69b4ffb (HEAD -> master) fix(緩存): 修復產品接口緩存bug
* eb0121a (HEAD->master) feat(測試提交): 測試代碼
* e618321 fix(頁面展現): 展現錯誤修復
複製代碼
rebase代碼原則:
特性分支合併master代碼使用 rebase,總讓當前特性處於最近提交; 若是一個特性有多個同事開發,rebase以前記得讓其餘同事提交全部代碼,rebase以後記得讓其餘同事強制更新本地代碼;
Git 提交的正確姿式:Commit message 編寫指南 你可能會忽略的 Git 提交規範 Git鉤子:自定義你的工做流 用 Node.js 寫前端本身的 Git-hooks gist.github.com/jasonrobert…
首次發佈於:一個維護版本日誌整潔的Git提交規範