rebase は「引っ越し」ではなく「建て直し」

同じ設計図から、新しい土台の上に建て直す
同じ設計図から、新しい土台の上に建て直す

rebase の前と後で git log を見比べると、気づくことがある。rebase 前は 4db25b5 だった「Add about page」のコミットが、rebase 後はまったく別のハッシュに変わっている。同じ変更なのに ID が違う。rebase はコミットを引っ越しさせたのではなく、中身をコピーして新しいコミットに作り直したのだ。

ハッシュは、中身(スナップショット・親・作者・日時・メッセージ)から計算される指紋。rebase で親(分岐元)が変われば、ハッシュも必ず変わる。元のコミットは消えるのではなく、参照されずひっそり残るだけだ(しばらくは git reflog で拾える)。つまり rebase は履歴を「書き換える」操作。一直線に見えるのは、古い枝を捨てて建て直した結果なのである。

ここまで分かると、「push 済みの履歴は rebase しない」という鉄則も腑に落ちる。作り直したコミットは、他の人が持つコミットとは別物。共有済みの履歴を建て直すと全員の履歴と食い違い、混乱を招く。だから rebase は手元だけのコミットに使うのが原則だ。ローカル限定なら、好きなだけ整えていい。