LoginSignup
142
129

More than 5 years have passed since last update.

お前らのコミットメッセージは間違っている!! (JavaScriptでGit Hooks)

Posted at

TL;DR

コミットメッセージにプレフィックスをつけるとログの検索効率が上がる、レビュアーが見た時わかりやすい、プレフィックス単位でコミットの粒度を揃えられるなど利点多数。
⬇️
でも形式がその時でまちまち、忘れたりタイポしてしまう。(個人開発ではめんどくさがってやらない)
⬇️
「Git Hooks」という仕組みを利用すれば、コミットメッセージのフォーマットチェックを行い、強制させることができる。
⬇️
ネット上のGit Hooksのサンプルコードはシェルスクリプトばかり😇めんどい、わからない、シェル職人芸が必要(!?)。
⬇️
「husky」を使えば(Node)JSでも簡単にいけるぞ〜

そんなお話!!

プレフィックス

プレフィックスのルールについては、以下の方の記事が参考になります。
【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話

Git Hooksについて

コミットやプッシュなどをトリガーに任意のスクリプトを実行することができる仕組み。
今回紹介するコミットメッセージのチェックや、プッシュ直前にテストを実行、ソースにデバック用コード(console.log)などの消し忘れチェックなどにも使える。

詳しくは以下を参照
Git公式「Git のカスタマイズ - Git フック」

ここで一つ問題なのが、フック本体は.gitディレクトリ配下にあるので、プロジェクトメンバー間で共有できないのである!!
image.png

husky

前述の問題は、Node.jsプロジェクトであれば「husky」を導入することで簡単に解決できる。

npm install husky --save-dev 

package.jsonに追記


{
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "pre-push": "npm test",
      "...": "..."
    }
  }
}

実践

任意のディレクトリにソースファイルを配置して呼び出すだけ
コミットメッセージをチェックしたければ、「commit-msg」にフックさせる。
image.png
コミットメッセージは.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」を導入するとこんな感じでターミナルに表示させることができる。
image.png

おまけ

よくある「マスターブランチにプッシュしちゃった☆いっけねー てへぺろ☠️」など
任意のブランチへのプッシュを防止するには「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);
}
142
129
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
142
129