世界を動かす技術を、日本語で。

Gitノート: Gitの最もクールで、最も愛されていない機能 (2022)

概要

  • git notes はメタデータをコミットなどに付与できる Gitの隠れた機能
  • コミットメッセージの後付け修正 やコードレビュー結果の保存に活用例
  • 使い勝手の悪さや GitHub非対応 で普及が進まず
  • 分散型コードレビュー やオフラインでのメタデータ管理の可能性
  • git notes の今後の発展と普及への課題

git notesとは何か

  • git notes は既存のGitオブジェクト(コミット、blob、treeなど)に 追加情報(メタデータ) を後付けできる機能
  • 既に履歴に記録された コミットメッセージを直接修正できない 場合でも、後から情報を notesとして追記 可能
  • オブジェクト本体を変更せずに メタ情報の追記 ができる仕組み
  • 例:最新コミットにnotesを追加
    • git notes add -m 'Acked-by: <tyler@tylercipriani.com>'
  • git logNotes欄 として表示される

git notesの実用例

  • The Gitプロジェクト ではコミットと メーリングリストの議論スレッド をnotesで紐付け
  • 他の利用例
    • 各コミットやブランチごとの 作業時間の記録
    • レビューやテスト情報 の記録
    • 分散型コードレビュー システムの構築

コードレビュー・テスト結果の保存

  • Gerritのreviewnotesプラグイン により、レビュー情報をnotesで管理
    • オフラインで 誰がレビューしたかどんなテストを通過したかgit logで確認可能
    • 例:
      • git fetch origin refs/notes/review:refs/notes/review
      • git log --show-notes=review
  • コミットに紐づく詳細なレビュー履歴 をリポジトリ内で一元管理

分散型コードレビューの実現

  • Googleのgit-appraise など、git notesを活用した 完全分散型コードレビューシステム の登場
    • レビュー依頼・コメント・マージ も全てローカルで完結
    • オンラインサービス(GitHub等)依存しない 独立性
    • シンプルなWebインターフェースも提供

git notesの課題と現状

  • 使い勝手の悪さ (UIやコマンドの複雑さ)が普及の妨げ
  • GitHubは2014年以降、commit notesの表示を廃止
  • blobやtreeへのnotes追加はさらに煩雑
  • 一部設定でgit logへの表示やfetchの自動化は可能
    • 例:
      • git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*'
      • git config notes.displayRef 'refs/notes/*'
  • 依然として マイナーで忘れられがちな機能

フォージ独立性と今後

  • Git自体が分散型バージョン管理システム である点を活かし、 git notes でプロジェクトの履歴やメタデータも 分散管理 可能
  • 中央集権的なサービス(GitHub等)依存からの脱却 を目指す動き
  • git notesの普及・改善 が進めば、より柔軟でオープンな開発フローの実現も可能性

Hackerたちの意見

Gitノートは、コミット後に頻繁にテキストを追加して他の人に見えるようにしないと、あんまり面白くないよね。Acked-Byやメーリングリストのディスカッションリンクの例は、あんまり良い例じゃない気がする。これらはコミット時にはもう知ってることが多いし。gitのコミットメッセージは基本的に無限の長さが持てるから、フォージで行われたコミットに関するすべてのディスカッションをそのままコミットメッセージにコピーすることもできるよ。私が思うに、もっと良い例としては、後でリバートされたコミットにgitノートを追加することかもしれない。

コミットが作成された後も、ディスカッションは続けられるよ。

Acked-Byやメーリングリストのディスカッションリンクの例は、あまり良い例じゃない気がする。これらはコミットが行われる前にすでに知られている可能性が高いからね。コミットに関するディスカッション(is: review)やコミットの承認は、コミットが行われる前にはできないよ。 > もっと良い例として考えられるのは、後で元に戻されたコミットにgitノートを追加することかな。コミットメッセージの方がこの用途には向いてると思う。ファイルにブレームをかけると、そのファイルの最新の変更が表示されるよね。もしあるコミットが別のコミットの変更を元に戻した場合、その古いコミットを元に戻す新しいコミットがブレームに表示される。

現在の役割では、gitノートをかなり活用してるよ。内部コードレビューを追跡するための実験から始めたんだけど、コミットメッセージを埋め尽くしたり、すべてにPRを作ったりしないで済むからね。各コミットには、それがどのチケットに関連しているか、インフラの制約、修正の場合はインシデントスレッドへのリンクなどのコンテキストをタグ付けしてる。全部リポジトリに保存されてるから、なぜ行が変わったのかを知るためにSlackやJiraをグレップする必要がなくなるんだ。スケールで使い始めると、プラットフォームのUIがどれだけ必要ないかに気づくよ。ビルドの再現性についてはよく話すけど、意図についてはあまり話さないよね。もしかしたら、ここから始まるのかも。

それはコミットメッセージじゃないの?それとも「このコミットがバグ#123を引き起こしたことに気づいた」みたいに、未来にリンクさせることが目的なのかな?

これはUIの問題であって、知識不足の問題じゃないよ。もしGitHubのUIがノートを表示したら、すぐにもっと使われるようになると思う。

うん、GitHubがこれをサポートしてくれたらいいのに。

あまり知られていないもう一つの機能はgitトレーラーだよ: https://alchemists.io/articles/git_trailers これは、コミットを作成する際に含めることができるキーとバリューの構造データなんだ。一部のシステムではメタデータを付加するために使われてるよ。例えば、Gerritはこれを使ってChange-Idを付加してる。

別のシステムからのもう一つの似た機能:PostgreSQLのCOMMENT https://www.postgresql.org/docs/17/sql-comment.html これを使うと、PostgreSQLのさまざまなデータベースオブジェクトにテキストを付加できるんだ。もっと構造化されたキーとバリューのデータベースオブジェクトメタデータを編集できる機能があればいいのに。

うん、トレーラー大好き。特定のことにノートを使おうとしたことがあったけど、ちょっと面倒だった記憶があるな(具体的にどんな障害があったかは覚えてないけど)。トレーラーは私のニーズにぴったり合ってたよ。

これは素晴らしい!チケット番号とかを使ってCIを強化できそうだね。

最近、GitHubがコミットメッセージの中に[skip ci]を含める代わりにこれを使っていることを知ったんだけど、下流の利用者がコミットメッセージを簡単に削除できるためだと思う。https://docs.github.com/en/actions/managing-workflow-runs-an... なぜ最後のトレーラーであることを義務付けているのかはわからないけど、正規表現の理由かな。

Hacker Newsで議論の続きを見る