📙

【Git】業務でコミットメッセージの接頭語testを使うとき、コミットの順番や接頭語選びに迷いつつ、現場の空気を読んで寄せてコミットするよね

に公開

はじめに

https://zenn.dev/noranuko13/articles/b30c8ed65e8e27

対象

  • コミットメッセージの接頭語・型に迷える子羊向け。

なお全て読んでも迷いは晴れません。コメント欄を「うちはこうしてる」「私も悩んでる」など、知見共有や議論の場にしていただければ、文殊の知恵の一つでも出てくるんでないかと思います。

コミットメッセージの接頭語・型

Conventional Commitsというコミットメッセージの仕様があります。ここでは型と呼ばれています。詳しくはリンク先を参照。知らなくても感覚的に使っている方が多いんでないかと思います。

https://www.conventionalcommits.org/ja/v1.0.0/

日本語の技術記事だと、接頭語・接頭辞などと呼ばれることも多いです。結構沢山の接頭語を見かけますが、実際のプロジェクトで利用するものは一部。

https://qiita.com/muranakar/items/20a7927ffa63a5ca226a

そもそも接頭語の存在を知らない方も、「そういうルールでコミットメッセージを運用している現場もあるんだな」くらい知っておけば、この記事は読めると思います。

なぜコミットメッセージの接頭語に迷うのか

意味や範囲が重複しすぎている

そもそもテストコードは常に付いて回るものです。新機能の開発、機能改修、不具合の修正、リファクタリング、テストの設定自体の修正、ライブラリのバージョンアップ。どれを選んでも片足突っ込んでて、集合でいえば微妙に重なりまくってる接頭語ではありませんか。

例えばremove,deleteは何らかの機能を除去・削除するように見えますが、業務レベルで使うときに何がどう違うというのか。ちなみに英語レベルだとdeleteは完全削除、removeは一時的に取り除くなどの違いがあるようです。

しかしGitを利用している以上、戻そうと思えば戻せますし。では仮にremoveだけを使うようにするとして、テストコードを削除した場合、果たしてこれはremoveなのかtestなのか。

この修正はどの接頭語なのか問題が常に付きまとい、コミットする単位やコミットメッセージ本文に少なくない影響を与える訳です。テストの修正はコードを修正するほぼ全ての対応について回るのですから、ある程度機械的なフローチャートを用意しないとやってられません。

テストコードはいつコミットするべきか

テスト駆動開発では先に落ちるテストコードを書くのが定石。ならばテストが落ちる状態のコードを、testを付けて先にコミットするのが時系列的には正しいでしょう。

リアルな現場の話をすると、厳密なテスト駆動開発はしてないことが多いです。ある程度の実装が済んでから、「いつの間にか動かなくなった」を防ぐ目的でテストコードを書くという順番です。この場合、テストコードのコミットはほぼ同時か、後からコミットすることになります。

そもそもテストコードを分けてコミットするか、という話もあって。これがリファクタリングならテストコードと本体の修正を同時に行うのは問題があるので、別々にコミットするか、プルリクごと分けるくらいでもいいと思いますが。

mainにマージするときに動いていればいいのか、コミット単位でも動いているものをコミットするのか。個人的には特定のコミットをチェックアウトしたときに、正しく動かないのは居心地が悪いのですが、テスト駆動開発ではRed->Green->Refactoringが定石であるからして。

結論:郷に入っては郷に従え

ここまで長々と書いてきましたが、最終的には現場に入ってから直近のコミットメッセージをざっと眺めて真似をするのが無難ですよね。そもそも接頭語がない現場もありますし、コミットメッセージがWIP🍻だけの現場だってあるのですから。

大抵は雑多なように見えて、担当者や修正箇所によって法則めいたものが見えてくるので、あとはそれっぽいコミットメッセージにしてコミットすると。もちろんあまりにもあれな場合、後任の優秀なITエンジニアに怒られない程度には、情報を加えておきたいところですが。

そこで問題になるのは完全に一任されたときの開発。とりまConventional Commitsに習うのが間違いがないと推測されますが、あの仕様を面倒だと思う開発者もおりますし、「このチームではどうしたい?」「今まではどうしてた?」って話になってきますし。

今のところ出ている対処方法

テストコードと本体でコミットを分ける

仕様に則り可能な限りコミットを分ける方法です。問題は記事の前半で説明した通り、厳密でない場合にいちいち迷うと。

内容が重複になりそうなので、短いですがこの辺で。

余談になりますが、この方法だとコミット粒度は必然的に細かくなります。テストコードだけではなく、他の接頭語についても同様の基準で選定するので、choreでライブラリを導入して、featで新規画面を追加して、changeで既存のメニューに追加するみたいな。

それで粒度が細かすぎるというなら、GitHubでSquash mergeできないこともないのですが、デメリットを考えると採用は慎重になった方がいいと思います。業務上、責任の所在や不具合発生時の調査など考えると、下手なことをせずにマージコミットを作っておくのが無難かと。

複数付けて同時にコミットする

最初に引用しておくと、可能な限り分割しなさいと書かれています。

コミットが複数のコミット型からなるような場合はどうすればよいですか?
可能な限り、引き返して複数のコミットに分割します。 Conventional Commits の利点のひとつは、より組織化されたコミットとプルリクエストを行う事を可能にする事です。
Conventional Commits

どこの現場で見たか忘れましたが、

  • test:refactor: コミットメッセージ
  • feat:test: コミットメッセージ

みたいなパターンも見かけた気がします。要は当てはまるもの、全部付けとけ的なやり方です。先述の仕様には反していますが、重複するコミットを表現するという意味ではアリか?

比較的コミット粒度の大きい現場では、これが主流だったと思います(うろ覚え)。Rails scaffoldの単位で一気に修正してコミットしてしまうような。特段分ける理由もないのであれば、コミット分けるだけログを追うのも大変でしょうし、現場が回ってればヨシ。

迷うくらいなら接頭語testを使わない

複数付けて同時にコミットする方法と似ていますが、接頭語はただ1つのみ、本体のコードに合わせて使用します。

いちいち迷うコストを取っ払えるのは魅力的。以下の記事でも書きましたが、コミットメッセージの接頭語は開発者が混乱しない種類に限定した方がよいと思われます。

https://zenn.dev/noranuko13/articles/41df24877d3f3d

おわりに

個人開発では絵文字と独自フォーマットに振り切ってしまっていて、私が接頭語に対してどうこう言えた義理でもないのですが、ルールが整備されてないと悩みますよね。悩むのが面倒過ぎて、メモ(note)にかけてほぼ全部 🎶 になってる体たらく。

https://github.com/noranuko13/mpmm/commits/main/

最近のはちゃんと接頭語使ってますね。他の方が来るかもしれない中身というのもありますが。途中から変えるのも、それはそれで面倒ですから……検索性や統一性という意味で。

https://github.com/noranuko13/claudebox/commits/main/

いやしかしupdatechangeと直ぐに判別が付かないし、stylefixはどうするんだろうか。hotfixブランチで対応するなら、もはやブランチの状態で自明ではないのかhotfixfixchangeではないのか。いや仕様変更 at Hotfixブランチはそれ以前の問題でNGですが。

こういう自由にしていい部分て、決めるの難しいですよねえ。

Discussion