tyankatsu’s blog

カレーと炭酸が苦手なほうれん草好きマンの技術ブログとか

Gitに心躍ったあの日、そして今

TL;DL

  • angular の format と atom の emoji の組み合わせ最高
  • git config で commit 時に参照するファイルの設定が可能
  • でも Git の Commit Message はcommitizenを使いまわそう
  • commitlint で意図にそぐわない message フォーマットは排除しよう
  • 抜け道は CI で 防ごう
  • GUI ツールは知らん

commit message のフォーマットを意識しだした日

prefix

唐突に訪れたあの日。 それは前職場にフロントエンドエンジニアの人が来たことだった。
その人は commit message に独特の書き方を使っていた。

docs(README.md): :memo: コマンドの説明追加

なんだこの記法・・・ オラオラルールか?

ここで、気になる node package を彼が追加していた。generate-changelogというものであった。
CHANGELOG って web サービス作るときによく見るあれかという認識だった。
web サイト作るときにこんなの使わんよなぁと思いながら、好奇心が勝って一人で導入してみて捨てリポジトリで使ってみた。

breaking
build
ci
chore
docs
feat
fix
other
perf
refactor
revert
style
test

プレフィックスに使うと、そのルールに従ってよしなに CHANGELOG を生成してくれるというものだった。 なるほど、彼はこれを使いたいからこれ使ってただけかぁと一人で納得した。

じゃああの絵文字は?ってなった。

emoji

結構有名な記事だがこれを見つけて読んだ。
Emoji で楽しく綺麗なコミットを手に入れる | Goodpatch Blog
なにやらatom でも使われているらしい。
確かに見やすい。
🔥 とか絶対何か燃やした(消した)やん。これは僕も使いたいと思った。

作った format

なんやかんやあって、

git config --local commit.template ./path/to/hogehoge.txt

を使用することで、git messagevim モードに移行する際、このファイルを参照しながら commit が書けるということで、以下のフォーマットを用意した。


# ==== Format ====
# prefix(scope): :emoji: Commit body...
#
# backlog task key

# ==== prefix ====
# fix: バグやタイポなどの修正
# feat: 新しい機能の追加
# refactor: リファクタリング
# style: スタイリングに関わる変更(css/sass)
# chore: 細務(ファイル整備、移動、削除、名前変更など)
# test: テストファイルに対する変更や修正
# docs: ドキュメントの加筆や修正
# breaking: 破壊的変更
# build: ビルド周りの設定(主にgulpやwebpack周り)
# ci: CIに関わる設定
# pref: パフォーマンスの改善
# revert: 削除や変更の取り消し
# other: その他

# ==== scope ====
# eslint | eslint の設定を変更
# stylelint | stylelint の設定を変更
# config | config.json を変更
# readme | README.md を変更
# gulp | gulp の設定を変更
# webpack | webpack の設定を変更
# html | htmlファイル変更
# php | phpファイル変更
# js | jsファイル変更

# ==== Emojis ====
# 🐛  :bug: バグの修正
# 🎉  :tada: 新機能の実装
# 👍  :+1: 機能改善
# 💊  :pill: 機能修正
# 💉  :syringe: linterの設定やエラー修正
# 🔥  :fire: 不要ファイルの削除
# 🚚  :truck: ファイル移動
# 📛  :name: ファイル名変更
# 📝  :memo: markdownファイルの変更
# 📑  :bookmark: タグ切り(リリース)
# 👮  :cop: 認証周り
# ✅  :white_check_mark: テストの作成
# 💚  :green_heart: テストの修正
# 🆙  :up: モジュールのバージョンアップ
# 👻  :ghost: 作業途中

# ==== 7つのルール ====
# 1. タイトルの後は1行空けて本文を書く
# 2. タイトルを50字以内におさめる
# 3. タイトルの文頭を大文字にする
# 4. タイトルの文末にピリオドを付けない
# 5. タイトルは命令形で記述する
# 6. 本文は1行あたり72字以内におさめる
# 7. 本文ではどのようにではなく何をとなぜを説明する
#
# 詳細は https://postd.cc/how-to-write-a-git-commit-message/

最初に二行改行しているのは、参照するときに見やすくするため。 これを

git config --local commit.template ./gitmessage.txt

ってやって設定していた。
その他細かいことはREADME.mdに書いていた。(scope 増えたら txt ファイルに追記してねとか)
うーん、楽!!!便利!!!

この時アプリエンジニアの人に「選択式でできたら便利そう」って言われて、確かに・・・って思っていた。

commitizen との出会い

なんやかんやあって転職して、初めて出会ったのが、 commitizen
これは対話型のコマンドに答えるだけで commit message が作れるというものだった。

おいおいおい。最高かよ。

ってなった。

しかも、commitizen を眺めている途中で、AngularJS Git Commit Message Conventionsというものを見つけ、あーあれ(generate-changelog)で使ってた prefix はこれに準拠していたのかーと知る。
これ使えばいいじゃんとテンションは上がった。 しかし疑問が。

git は node 使わなくても commit できる・・・でも統一したいな?

GIT フックと NPM lifecycle

そこで、Git フックcurrent lifecycle eventを調べた。

なるほど、フックさせればいいのか。
Git フックでコミットメッセージを監視して、違うとエラーにして突き返す方法もある。
が、僕は node でさくっと監視させる環境にしたい。

node を駆使して監視体制を作る

commit message 絶対統一させるマン - Speaker Deck

これで紹介しているが、リポジトリを作った

husky で Git hook を簡略化した。

また、commitizen のフォーマットを日本語に変更する パッケージを改造して、emoji を追加できるようにした。

抜け道防ぐ

circleCI を設定し、CI 上で commitlint が走るので、

  • git commit --no-verify
  • node 入れずに git コマンド使う人

は、フォーマットが違うとエラーになる。
自力で頑張ってね、楽したかったら node でやってねシステムになっている。

commitizen への不満

今回自分でフォーマットを改造したのだが、これは、commitizen のフォーマットを日本語にしてくれる cz-conventional-changelog-jaを改造して自分で対話の項目(emoji)を増やしている。

もっと簡単にフォーマット拡張できるようにしたいなぁ

と思った。

調べてみるとこんなのがあった。 cz-customizable。 使ってみたが、僕の想像と違ったし、インターフェースなんか難しかったしイケてなかった。

パッケージを自作

仕方がないなぁと思い、自分でパッケージ作ることにした。
cz-format-extension

まだ WIP だけど、使うことは可能(拡張不可能)。
これから rc ファイル作って、そこに json 形式で情報書いたら拡張できるようにしていくつもり。

ところで GUI で Git ポチポチしてる人は?

sourcetree とかのやつですかね?
git hook に引っ掛けることはできるかもしれないですが、めんどくさいので他の記事を参考に自分でやってみてください。