commit規範方案探討

緣由

爲什麼要對commit進行規範化,每一次commit msg寫啥,又不會影響我的代碼運行?

確實,Commit的頻率和信息多少,並不會影響你代碼的執行,但是當你遇到需要上線分支中的一部分功能,想要cherry-pick的時候,就會很難受,commit msg清一色都是update xxx,也不知道要把哪些commit 找出來。

在項目開發開發中或許我們能經常看到

  • 說不出所以然的一連串的 commit 提交日誌
  • commit 信息寫的很簡單,根本沒有辦法從 commit 信息中獲知該 commit 用意的
  • commit 信息寫的很隨意,commit 信息和變更代碼之間不能建立聯繫的
  • commit 信息寫的過於冗餘的

相信或多或少大家都曾碰到過。一旦涉及代碼回滾,issue 回溯,changelog,語義化版本發佈等操作時,你基本是無從下手的。

那,我們要做的是什麼呢?

將commit 和 代碼之間能建立起聯繫,並和相關的 issue 予以關聯,做到任何代碼都能區域性的解決問題。而 changelog,語義化版本發佈這更像是合理化 commit 後水到渠成之事。

最佳實踐

1) One Thing,One Commit;

在提交 commit 的時候儘量保證這個 commit 只做一件事情,比如實現某個功能或者修改了配置文件。

2)不要commit一半的工作;

當開發任務沒有完整的完成的時候,不要commit。這不是說每次commit都需要開發完成一個非常完整的大功能,而是當把功能切分成許多小的但仍然具備完整性的功能點的時候,開發人員需要完整完成這個功能點之後才能commit。必要時可以使用stash命令對修改進行記錄。

3)經常commit;

經常使用commit能夠使你的commit(裏的修改內容)越小,並且能使你commit相關的修改,多次commit允許你推送自己代碼到遠程分支上的頻率增加,能有效的減少merge代碼時出現的代碼衝突問題,因爲多次 commit能使你的同事的代碼庫得到及時的更新。

4)commit之前的測試;

保證你所開發的功能是完整無誤的。在commit代碼之前的對代碼充分測試是非常重要的,可以避免有問題的代碼被其他開發人員使用。

5)編寫規範的commit message;

規範的Commit Message,就是奧利給!

規範

Angular Commit 規範

參考資料:Commit message 和 Change log 編寫指南

每次提交,Commit message 都包括三個部分:Header,Body 和 Footer。

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

Header部分只有一行,包括三個字段:type(必需)、scope(可選)和subject(必需)。

Body 部分是對本次 commit 的詳細描述,可以分成多行。

Footer 部分是對不兼容變動和關聯的issue進行描述。

graph TB CommitMessage --> Header CommitMessage --> Body CommitMessage --> Footer Header --> Type Header --> Scope Header --> Subject Body --> Description Footer --> A[BREAKING CHANGE] Footer --> B[Issue]

thoughtbot 規範

地址:https://github.com/thoughtbot/dotfiles/blob/master/gitmessage

# 50-character subject line
#
# 72-character wrapped longer description. This should answer:
#
# * Why was this change necessary?
# * How does it address the problem?
# * Are there any side effects?
#
# Include a link to the ticket, if any.
  1. 第一行不超過 50 個字符
  2. 第二行空一行
  3. 第三行開始是描述信息,每行長度不超過 72 個字符,超過了自己換行。
    1. 描述信息主要說明:
    2. 這個改動爲什麼是必要的?
    3. 這個改動解決了什麼問題?
    4. 會影響到哪些其他的代碼?
  4. 最後最好有一個相應 ticket 的鏈接

Commit 這種格式有點類似郵件,主題不超過50個字符,然後空一行,這樣顯示的下面的部分都會摺疊起來,類似下面的樣子。我們使用命令 git log --oneline的時候就只顯示第一行。

工具

參考資料:commitizen + husky 規範git提交信息

輸入提示信息

commitizen

cz-conventional-changelog

cz-conventional-emoji

lint工具

@commitlint/config-conventional

@commitlint/cli

自定義lint

commitlint-config-cz

cz-customizable

捕獲commit

husky

生成changelog

standard-version

方案1

交互式提交+Commit規範

第一步:安裝

yarn add -D commitizen cz-conventional-changelog @commitlint/config-conventional @commitlint/cli husky

第二步:配置

package.json


"scripts": {
  "commit":"git-cz",
},


"config":{
    "commitizen":{
        "path":"node_modules/cz-conventional-changelog"
    }
},

"husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
}

commitlint.config.js

module.exports = {
    extents:[
        "@commitlint/config-conventional"
    ],
    rules:{
        'body-leading-blank': [1, 'always'],
        'footer-leading-blank': [1, 'always'],
        'header-max-length': [2, 'always', 72],
        'scope-case': [2, 'always', 'lower-case'],
        'subject-case': [
            2,
            'never',
            ['sentence-case', 'start-case', 'pascal-case', 'upper-case']
        ],
        'subject-empty': [2, 'never'],
        'subject-full-stop': [2, 'never', '.'],
        'type-case': [2, 'always', 'lower-case'],
        'type-empty': [2, 'never'],
        'type-enum': [
            2,
            'always',
            [
                'build',
                'chore',
                'ci',
                'docs',
                'feat',
                'fix',
                'improvement',
                'perf',
                'refactor',
                'revert',
                'style',
                'test'
            ]
        ]
    }
}

方案2

交互式提交+自定義提示文案+Commit規範

第一步:安裝

yarn add -D commitizen cz-conventional-changelog @commitlint/config-conventional @commitlint/cli commitlint-config-cz cz-customizable husky

第二步:配置

和方案1類似,只是在其基礎上修改如下配置:

package.json

"scripts": {
  "commit":"git-cz",
},

"config": {
    "commitizen": {
      "path": "node_modules/cz-customizable"
    }
},


"husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
}

commitlint.config.js

// 增加cz
{
  extends: ["@commitlint/config-conventional", "cz"],
}

.cz-config.js

module.exports = {
  types: [
    {      value: 'init',      name: 'init:     初始提交'    },
    {      value: 'feat',      name: 'feat:     增加新功能'    },
    {      value: 'fix',      name: 'fix:      修復bug'    },
    {      value: 'ui',      name: 'ui:       更新UI'    },
    {      value: 'refactor',      name: 'refactor: 代碼重構'    },
    {      value: 'release',      name: 'release:  發佈'    },
    {      value: 'deploy',      name: 'deploy:   部署'    },
    {      value: 'docs',      name: 'docs:     修改文檔'    },
    {      value: 'test',      name: 'test:     增刪測試'    },
    {      value: 'chore',      name: 'chore:    更改配置文件'    },
    {      value: 'style',      name: 'style:    代碼樣式修改不影響邏輯'    },
    {      value: 'revert',      name: 'revert:   版本回退'    },
    {      value: 'add',      name: 'add:      添加依賴'    },
    {      value: 'minus',      name: 'minus:    版本回退'    },
    {      value: 'del',      name: 'del:      刪除代碼/文件'    }
  ],
  scopes: [],
  messages: {
    type: '選擇更改類型:\n',
    scope: '更改的範圍:\n',
    // 如果allowcustomscopes爲true,則使用
    // customScope: 'Denote the SCOPE of this change:',
    subject: '簡短描述:\n',
    body: '詳細描述. 使用"|"換行:\n',
    breaking: 'Breaking Changes列表:\n',
    footer: '關閉的issues列表. E.g.: #31, #34:\n',
    confirmCommit: '確認提交?'
  },
  allowCustomScopes: true,
  allowBreakingChanges: ["feat", "fix"]
};

交互界面

方案3

交互式提交+emoji表情包

第一步:安裝

yarn add -D commitizen cz-conventional-emoji

第二步:配置package.json,增加以下配置

"scripts": {
  "commit":"git-cz",
},
"config":{
  "commitizen":{
    "path":"node_modules/cz-conventional-emoji"
  }
},

方案4

全局模式,等同於方案1,只是cz全局安裝

第一步:安裝

# 全局安裝
npm install -g commitizen cz-conventional-changelog
# 項目內安裝
yarn add -D @commitlint/config-conventional @commitlint/cli husky

第二步:配置

.czrc

需要在全局根目錄(在命令行工具,輸入cd ~,就可以找到)下建立.czrc文件,然後文件中輸入內容{“path”:"cz-conventional-changelog"}或者鍵入如下命令:

echo '{"path":"cz-conventional-changelog"}' > ~/.czrc

package.json

"husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
}

commitlint.config.js 配置等同於方案1.

方案5

基於方案2再擴展

如果我們希望使用emoji,可以接受部分commitlint規範關閉,我們其實可以基於方案二直接擴展emoji。

第一步:安裝

# 全局安裝
npm install -g commitizen cz-conventional-changelog
# 項目內安裝
yarn add -D  @commitlint/config-conventional @commitlint/cli commitlint-config-cz cz-customizable husky

第二步:配置

package.json

# 配置自定義commit
"config": {
    "commitizen": {
      "path": "node_modules/cz-customizable"
    }
},
# 配置commit信息校驗
"husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
}

.czrc

需要在全局根目錄下建立.czrc文件,然後文件中輸入內容{“path”:"cz-conventional-changelog"}或者鍵入如下命令:

echo '{"path":"cz-conventional-changelog"}' > ~/.czrc

.cz-config.js

module.exports = {
  types: [
    { value: "✨feat",          name: "feat:          增加新功能" },
    { value: "🐛fix",           name: "fix:           修復bug" },
    { value: "📝docs",          name: "docs:          修改文檔" },
    { value: "⚡️perf",           name: "perf:          性能優化" },    
    { value: "🎉init",          name: "init:          初始提交" },
    { value: "➕add",           name: "add:           添加依賴" },
    { value: "🔨build",         name: "build:         打包" },
    { value: "🔧chore",         name: "chore:         更改配置文件" },
    { value: "👷ci",            name: "ci:            CI部署" },
    { value: "🔥del",           name: "del:           刪除代碼/文件" },
    { value: "♻️refactor",      name: "refactor:      代碼重構" },
    { value: "⏪revert",        name: "revert:        版本回退" },
    { value: "🍱style",         name: "style:         樣式修改不影響邏輯" },
    { value: "✅test",          name: "test:          增刪測試" },
  ],
  scopes: [],
  messages: {
    type: "選擇更改類型:\n",
    scope: "更改的範圍:\n",
    // 如果allowcustomscopes爲true,則使用
    // customScope: 'Denote the SCOPE of this change:',
    subject: "簡短描述:\n",
    body: '詳細描述. 使用"|"換行:\n',
    breaking: "Breaking Changes列表:\n",
    footer: "關閉的issues列表. E.g.: #31, #34:\n",
    confirmCommit: "確認提交?",
  },
  allowCustomScopes: true,
  allowBreakingChanges: ["feat", "fix"],
};

commitlint.config.js

module.exports = {
  extends: ["@commitlint/config-conventional", "cz"],
  rules: {
    "body-leading-blank": [1, "always"],
    "footer-leading-blank": [1, "always"],
    "header-max-length": [2, "always", 72],
    "scope-case": [2, "always", "lower-case"],
    "subject-case": [
      2,
      "never",
      ["sentence-case", "start-case", "pascal-case", "upper-case"],
    ],
    "subject-empty": [0],
    "subject-full-stop": [2, "never", "."],
    "type-case": [0],
    "type-empty": [0],
    "type-enum": [0],
  },
};

使用

我們採用了 方案5 作爲最終方案。

本地模式

git add後,執行 npm run commit 或者 yarn commit,就可以開始使用了。

全局模式

git add後,執行 git cz ,就可以開始使用了。

常用type

feat: 新功能(feature)
fix: 修改Bug
refactor: 重構(即不是新增功能,也不是修改bug的代碼變動)
docs: 文檔修改
style: 代碼格式(風格)修改, 注意不是 css 修改(不影響代碼運行的變動)
test: 測試用例修改
chore: 其他修改, 比如構建流程, 依賴管理.

standard-version

第一步:安裝

yarn add standard-version -D

第二步:配置

配置package.json

"scripts": {
    "release": "standard-version"
}

第三步:運行

執行 yarn release 生成CHANGELOG.md。

參考

http://legendtkl.com/2016/12/22/git-good-practice-commit-msg/

https://juejin.im/post/5cc7be8bf265da036c579597

https://segmentfault.com/a/1190000009048911

https://shimo.im/docs/18AlXO42yGIgFxAB/read

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章