# 偉大的 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)