Skip to content

GerritのChange-Idとは何か

Gitは本来、コミット自体を更新すると異なるハッシュとなって、変更前の状態を追跡することができなくなる。全て書き換えられるとレビュアーが過去にどこまで見たのか把握しづらくなるので、一度レビューされたコミットは書き換えずに新しいコミットを追加する方法が好まれる。しかしこの場合、今度はひとつの変更が複数のコミットに分離する状況が発生する。具体的には、

gitGraph
commit
commit id: "base"
branch feature-1
checkout feature-1
commit id: "A"
commit id: "B"
commit id: "C"

ここで AC に指摘が入って変更を行うと、

gitGraph
commit
commit id: "base"
branch feature-1
checkout feature-1
commit id: "A"
commit id: "B"
commit id: "C"
commit id: "fix of A"
commit id: "fix of C"

このとき、レビュアーは fix of A を見れば A との差分が確認できるけれど、後から変更の全体を知りたい場合は Afix of A の2つを見なければならない。2つ程度ならいいが、3つも4つもあると追跡が困難となる。従って本来はこのようになりたい。

gitGraph
commit
commit id: "base"
branch feature-1
checkout feature-1
commit id: "A'"
commit id: "B"
commit id: "C'"

GerritやTangledでは、GitのトレイラーChange-Id を記載しておくと、同じIDを持っているコミットはハッシュが異なっていても同じものだと扱うことができる。上記の図だと ABChange-Id となる。これによって、元のコミットを残さなくても差分を確認できるようになっている。

特に決まっていないが、Gerritでは先頭に I を付けたコミット内容のSHA1ハッシュを使う。

Change-Id: I00112233445566778899aabbccddeeff

宇佐見さんの記事によると、jj コマンドでは kz の16文字を Change-Id として使うらしい。

Gerrit Code Review - Change-Idsによると、Gerritの場合はレビューを受けるブランチ内でIDが一意となっていれば良い。具体的には以下の組で一意となることが求められる。従って異なるブランチに同一のIDがあっても問題ない。

  • リポジトリ名
  • ブランチ名
  • Change-Id

Change-Id 自体はGerrit由来かもしれないが、コミットをリライトすること自体はGit本来の設計で考慮されている。具体的には、Git自体の開発ではレビューの結果で修正が必要になった場合、V2として変更の全体を再送するスタイルを取っている。このとき

interdiff against v2

のような情報が追加されている場合があり、これが Change-Id と同等の役割を担っている。