TL;DR
コミットメッセージにプレフィックスをつけるとログの検索効率が上がる、レビュアーが見た時わかりやすい、プレフィックス単位でコミットの粒度を揃えられるなど利点多数。
⬇️
でも形式がその時でまちまち、忘れたりタイポしてしまう。(個人開発ではめんどくさがってやらない)
⬇️
「Git Hooks」という仕組みを利用すれば、コミットメッセージのフォーマットチェックを行い、強制させることができる。
⬇️
ネット上のGit Hooksのサンプルコードはシェルスクリプトばかり😇めんどい、わからない、シェル職人芸が必要(!?)。
⬇️
「husky」を使えば(Node)JSでも簡単にいけるぞ〜
そんなお話!!
プレフィックス
プレフィックスのルールについては、以下の方の記事が参考になります。
【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話
##Git Hooksについて
コミットやプッシュなどをトリガーに任意のスクリプトを実行することができる仕組み。
今回紹介するコミットメッセージのチェックや、プッシュ直前にテストを実行、ソースにデバック用コード(console.log)などの消し忘れチェックなどにも使える。
詳しくは以下を参照
Git公式「Git のカスタマイズ - Git フック」
ここで一つ問題なのが、フック本体は.gitディレクトリ配下にあるので、プロジェクトメンバー間で共有できないのである!!
husky
前述の問題は、Node.jsプロジェクトであれば「husky」を導入することで簡単に解決できる。
npm install husky --save-dev
package.jsonに追記
{
"husky": {
"hooks": {
"pre-commit": "npm test",
"pre-push": "npm test",
"...": "..."
}
}
}
実践
任意のディレクトリにソースファイルを配置して呼び出すだけ
コミットメッセージをチェックしたければ、「commit-msg」にフックさせる。
コミットメッセージは.git/COMMIT_EDITMSGファイルの記載内容をチェックするばおk
/* git hoooks commit-msg */
/* コミットメッセージのprefix確認 例: hoge: */
const boxen = require('boxen');
const fs = require('fs');
// プレフィックス一覧
const prefix = ['fix', 'add', 'feat', 'refactor', 'perf', 'style'];
//コミットメッセージ取得、チェック
let git_message = fs.readFileSync('./.git/COMMIT_EDITMSG', 'utf8').trim();
let isMissmatch = !prefix.some(str => {
let pattern = new RegExp(String.raw`^${str}:\s.*`, 'i');
return git_message.match(pattern);
});
if(isMissmatch){
console.error(boxen('☠⚠️コミットメッセージにプレフィックスをつけてね @delmontz prefix:半角スペース ⚠️️☠', {
borderStyle: 'double',
align: 'center'
}));
//異常終了 コミット中止
process.exit(1);
}else{
//正常終了
process.exit(0);
}
ちなみに
「boxen」を導入するとこんな感じでターミナルに表示させることができる。
おまけ
よくある「マスターブランチにプッシュしちゃった☆いっけねー てへぺろ☠️」など
任意のブランチへのプッシュを防止するには「pre-push」にフックさせる
const execSync = require('child_process').execSync;
const boxen = require('boxen');
const branch_name = execSync(`git branch --contains`).toString().match(/\* (?:\(no branch, rebasing )?([^)\n]+)/)[1];
if (branch_name === 'master' || branch_name === 'release') {
console.error(boxen(`☠⚠️⚠️⚠️${branch_name}ブランチにpushしないで!! @delmontz⚠️⚠️⚠️️☠`, {
borderStyle: 'double',
align: 'center'
}));
//異常終了 push中止
process.exit(1);
}else{
//正常終了
process.exit(0);
}