# 偉大的 Git commit message rules
###### tags: `work` `done`
請大家訂閱收藏加讚賞 <3
* 來源:[Commit Message rules](https://hackmd.io/VHVoqzLmTDaTFvV_Al_RbA) by SHU HENG CHEN
[toc]
## Golden rule
> for adding human and machine readable meaning to commit messages
### [The seven rules of a great GIT commit message](https://chris.beams.io/posts/git-commit/)
1. 標題與內容中間多一行空白
1. 標題限制 50 字元
1. 標題第一個字必須為大寫
1. 標題最後不要帶上句號
1. 標題內容可以使用強烈的語氣
1. 內容每 72 個字元斷行
1. 內容可以多解釋 what and why vs. how
### 概念
* 應獨立 commit 每個不同意義的異動(issue),commit 才會跟異動的程式碼有關聯。
* 每次 commit 須針對異動的檔案做說明:Why & What,讓日後進行維護人員更快進入狀況。
* 每次 commit 都加上 issue 編號,方便追蹤程式異動。
* 不能只把 Git 當作程式碼的 FTP,要把 Git 當作歷史查閱的工具才拿發揮 Git 的功能。
---
## Commit Message 規範組成:
![](https://i.imgur.com/p8qVhNw.png)
```python=
Header: <type>(<scope>): <subject>
- type 代表 commit 的類別:feat, fix, docs, style, refactor, test, chore,必要欄位。
- scope 代表 commit 影響的範圍,例如資料庫、控制層、模板層等等,視專案不同而不同,為可選欄位。
- subject 代表此 commit 的簡短描述,不要超過 50 個字元,結尾不要加句號,為必要欄位。
Body: 72-character wrapped. This should answer:
* Body 部份是對本次 Commit 的詳細描述,可以分成多行,每一行不要超過 72 個字元。
* 說明程式碼變動的項目與原因,還有與先前行為的對比。
Footer:
- 填寫任務編號(如果有的話).
- BREAKING CHANGE(可忽略),記錄不兼容的變動,
以 BREAKING CHANGE: 開頭,後面是對變動的描述、以及變動原因和遷移方法。
```
## format
```text
<type:類型>[optional scope:作用範圍(可省略)]:<description:描述>
//empty line here
[optional body:正文(可省略)]
//empty line here
[optional footer:頁腳(可省略)]
```
+ `type` : 由下列選項擇一
+ `build`(常用): Changes that affect the build system or external dependencies *(example scopes: gulp, broccoli, npm)*
+ `chore`: Updating grunt tasks etc; no production code change *(means nothing that an external user would see)*
==建構程序或輔助工具的變動==
> + implementation (of an existing feature, which doesn't involve a fix),
> + configuration (like the .gitignore or .gitattributes),
> + private internal methods...
+ `ci`: Changes to our CI configuration files and scripts *(example scopes: Travis, Circle, BrowserStack, SauceLabs)*
+ `docs`(常用): Documentation only changes
==文件類型檔案更動==
+ `feat`(常用): A new feature *(this correlates with **PATCH** in semantic versioning^[[semantic versioning](https://semver.org/#summary)])*
==新增/修改功能(feature)==
+ `fix`(常用): A bug fix *(this correlates with **MINOR** in semantic versioning)*
==修補bug==
+ `hotfix`:
==不影響主版本的更新==
+ `perf`(常用): A code change that improves performance
==改善效能==
+ `refactor`: A code change that neither fixes a bug nor adds a feature
==重構 (既不是新增功能,也不是修補 bug 的程式碼變動)==
+ `style`: Changes that do not affect the meaning of the code *(white-space, formatting, missing semi-colons, etc)*
==格式 (不影響程式碼運行的變動 white-space, formatting, missing semi colons, etc)==
+ `test`(常用): Adding missing tests or correcting existing tests
==增加測試==
+ `scope` : (optional)目前沒有統一的標準,通常會跟軟體開發方法而變
> Scope could be anything specifying place of the commit change
+ 元件導向範例:`init` `runner` `watcher` `config` `web-server` `proxy`
+ MTC範例: `model` `view` `controller`
+ 物件導向(類別名稱)
+ `description` : The subject contains a succinct description of the change
+ ==ENGLISH ONLY==
+ less than 50 characters
> 50字元的限制而是一個[經驗法則](https://stackoverflow.com/questions/2290016/git-commit-messages-50-72-formatting)。
> 讓標題保持在 50 字以下能夠確保標題的可讀性,並且強迫作者思考如何用更簡潔的方式表達發生什麼事情。
> 如果你很難總結出標題,這代表你可能在一個 commit 裏面做了太多的改變。請儘量讓 commits 單一化,一次只更動一個主題 (atomic commits)。
+ don't capitalize the first letter
+ no dot (.) at the end
+ use the imperative, present tense: "change" not "changed" nor "changes"
> 由於語言習慣問題,大家比較常使用指示性語句,來描述事實。為了避免這個問題,我們提供一個簡單的把戲來幫助大家完成正確的祈使句型
> 一個正確的 Git commit 標題應該要能夠代入下面的句型,使之成為完整的句子:
> + ==If applied, this commit will <你的標題>==
> ex:
> + If applied, this commit will update getting started documentation
> + If applied, this commit will update getting started documentation
> 若不正確使用祈使句,會導致句子語意不通順
> ex:
> + If applied, this commit will fixed bug with Y
> + If applied, this commit will changing behavior of X
+ `body` : (optional) more details than the `description` include motivation for the change and contrasts with previous behavior
> 解釋"what"和"why"(改變了"什麼"和"為什麼"改變)
+ less than 72 characters *per line*
+ use the imperative, present tense: "change" not "changed" nor "changes"
+ `markdown` style
+ ex:
```markdown
More detailed explanatory text, if necessary. Wrap it to
about 72 characters or so.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Use a hanging indent
```
+ `footer` : (optional) only needed for two cases: `break change` and `close issue`
+ `break change`: All breaking changes have to be mentioned in footer with the description of the change, justification and migration notes. *(this correlating with `MAJOR` in semantic versioning)*
+ start with the word `BREAKING CHANGE: <description>` and follow a newline .The rest of the commit message is then used for this.
+ format:
```text
<type>[optional scope]:< ><description>
//empty line here
[optional body]
//empty line here
BREAKING CHANGE:< ><description>
//empty line here
<detail>
```
+ ex:
```markdown
BREAKING CHANGE: isolate scope bindings definition has changed.
`port-runner` command line option has changed to `runner-port`, so that it is
consistent with the configuration file syntax.
To migrate your project, change all the commands, where you use `--port-runner`
to `--runner-port`.
```
+ `close issue`: Closed issues should be listed on a separate line in the footer prefixed with `Closes:`
+ format
```text
<type>[optional scope]:< ><description>
//empty line here
[optional body]
//empty line here
Closes< ><issue number list>
```
+ ex:
```markdown
Closes #123, #245, #992
```
+ ==special case== `revert`: If the commit reverts a previous commit, it should begin with revert: , followed by the header of the reverted commit. In the body it should say: This reverts commit \<hash\>., where the hash is the SHA of the commit being reverted.
+ format
```text
revert:< ><type>[optional scope]:< ><description>
//empty line here
This reverts commit <hash>
```
+ ex:
```markdown
revert: feat(pencil): add 'graphiteWidth' option
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
```
## 自動生成commit message格式
設定.gitmessage可產生範本,提醒大家遵守規範
1.建立template檔案
```text
<type:類型>[optional scope:作用範圍(可省略)]:<description:描述>
//empty line here
[optional body:正文(可省略)]
//empty line here
[optional footer:頁腳(可省略)]
```
![](https://i.imgur.com/Wslxq5C.png)
2.設定global參數
```python=
#設定template路徑
git config --global commit.template <檔案路徑>
#設定編譯器
git config --global core.editor <vim(欲使用的編譯器)>
```
設定完成後對專案輸入commit
![](https://i.imgur.com/YpxeMYW.png)
可發現commit message的預設內容為你設定的testtemplate
![](https://i.imgur.com/EdOQ9sK.png)
欲取消template,從~/.gitconfig文件中删除此部分即可(git config中刪除commit與core)
![](https://i.imgur.com/J46MaO2.png)
4.測試commit功能
## 自動檢查commit message格式
[commitlint](https://commitlint.js.org/#/?id=commitlint-nbsp-)可自動檢查commit message內容是否遵守規範
![](https://i.imgur.com/M3lzbM2.gif)
安裝方法如連結[commitlint](https://commitlint.js.org/#/?id=commitlint-nbsp-)(尚未測試)
## All-in-one solution
## reference
1. [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4)
2. [karma commit msg](http://karma-runner.github.io/0.10/dev/git-commit-msg.html)
3. [Commit message 和 Change log 编写指南](http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html)
4. [如何寫一個 Git Commit Message](https://blog.louie.lu/2017/03/21/%E5%A6%82%E4%BD%95%E5%AF%AB%E4%B8%80%E5%80%8B-git-commit-message/)
5. [优雅的提交你的 Git Commit Message](https://zhuanlan.zhihu.com/p/34223150)
6. [Git Commit Message 這樣寫會更好,替專案引入規範與範例
](https://wadehuanglearning.blogspot.com/2019/05/commit-commit-commit-why-what-commit.html)
7. [commit message 模板建立](https://blog.csdn.net/xct841990555/article/details/83449068?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control)