[Git] 機能の削除ではcommit prefixにrefactor!を使ってみよう

機能を削除した際のcommit prefixには何が適切かを考えてみました。
2022.06.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。サービスグループの武田です。

みなさん普段の開発でGitを使っている方は多いでしょう。その際コミットメッセージは気を遣っていますか?私が担当しているプロジェクトではConventional Commitsを意識的に使用しているケースが多いです。

簡単に言えば、機能の追加(feature)ではfeat、バグの修正(bug fix)ではfixといったprefixをコミットメッセージに付けようというものです。そうすることで、次のようなメリットが享受できます。

  • 各コミットの目的が明確になり、適した粒度になる
  • 人間が読んでわかりやすいコミットメッセージになる
  • 機械的に処理しやすくなる

さてこのcommit prefixは導入コストが低い割にメリットが大きいです。しかしどのprefixを付ければいいのか悩ましいケースがたまに出てきます。

機能の削除に付けるprefix

具体的に悩ましかったケースとして「機能を削除したコミット」があります。featは機能の追加ですので真逆。fixはバグの修正。refactorは挙動の変更を伴わないコード修正(リファクタリング)。choreはコード外の変更なので違う。あれ、ないですね?deleteやらremoveやらを独自に付与できますがエコシステムを考えると独自のものは避けたいです。

そこで「機能の削除」を次のように分解して整理してみます。

  1. 機能の追加ではない
  2. 挙動の変更を伴わない
  3. 破壊的な変更である

2が直感的にわかりにくいでしょうか。「あったものが消える」のは変更のように思えますが、A→A'となるのではなく、そもそもAが存在しなくなるので「挙動の変更ではない」ととらえます。

そうすると候補はrefactorとなります。ただし通常のリファクタリングと異なる点として「破壊的な変更」である点もポイントとなります。Conventional Commitsでは破壊的な変更はprefixに!をつけるか、フッタにBREAKING CHANGEを記載します。

以上を踏まえ、「機能を削除したコミット」にはrefactor!のprefixを付けるようにしてみました。

refactor!の副次効果

私が担当しているプロジェクトではCI/CDパイプラインとしてGitHub Actionsを利用しています。その中でSemVerを自動的に算出するアクションとしてGitHub Tagを利用しています。前回のバージョン以降のコミットを読み取り次のバージョンを算出してくれるのですが、同時にリリースノートも作成してくれます。

refactor!のprefixが付いたコミットを含んでいた際のリリースノートが次のものです。

Code RefactoringBREAKING CHANGE に該当コミットのメッセージが出されていました。この仕様を把握しておけば、リリースノートを見て機能が削除されたことも一目ですね。これはうれしい誤算でした。

まとめ

機能を削除した際にcommit prefixとして何が適切か結構悩んでいたのですが、ひとつの解を得ました。また考えが変わる可能性はありますが、しばらくはこの運用を続けてみます。