Gitのcommitとbranch:あなたのクソコミットはrebaseしても残っています

先日アイリッジの社内勉強会でgitの基礎概念を学んできたのでその共有です。初心者向け記事です。私自身が初心者なので不理解もあるかと思われます。間違ってたら編集リクエストを投げていただければ幸いです

はじめにコミットがあった

コミット、ブランチ、タグなどgitにはいろいろな概念があります。しかし、gitにおいて最も基本的な存在はコミットです。ブランチやタグのないコミットは存在しますが、コミットのないブランチは存在しません。

コミットが持つ情報ら主に以下の二つです。(時刻みたいな基礎情報は飛ばします)

  • コミット自体のid
  • 直前のコミットid
  • 直前との変更差分

直前との差分比較を繰り返して現状を表現するのがgitの基本です。直前のコミットidを持たないコミットは基本的に一つしか存在しません(二つ作った場合にはマージできない)。直前のコミットidを二つ持つコミットをマージコミットと言います(後述)。

ブランチはコミットとともにあった

では、ブランチとはなんでしょうか? ブランチは簡単にいえば、一連のコミットに名前をつけたものです。コミットは前にしか辿れないため、一つのコミットを決めると必然的に歴史は一つになります(マージは後述)。その一つの歴史に名前をつけたものがブランチです。

ブランチはコミットであった

ブランチに対して、コミットを保存するワークスペースのようなイメージを初心者は持ちがちです。しかし、正しくは、ブランチは一つの最新コミットその自体です。本質的には、最新のコミット情報があれば、ブランチの基本的役割は果たせます。

その他のgit操作

mergeとは?

マージとは、二つのコミットを親にもつコミットのことです。コンフリクトを解消してあれば、途中が二つに分岐していても最新状態の再現は可能です。

rebaseとは?

 rebaseは既存のコミットを元に新しいコミットを作り直すコマンドです。簡単にいえば、コンフリクトを解消して、別の親コミットを持った一連のコミットを作るだけです。

あなたのクソコミットはrebaseしても残っています

よくrebaseのことを歴史改変という人がいますが、それは正確ではありません。rebaseはコミットを作り直して、ブランチ名をつけ直すだけです。つまり、歴史を改変しているのではなく、新しい歴史書を作ってこれが正典だと主張しているだけです。本当の歴史はちゃっかり残っています。

まとめ

  • gitはコミットありき
  • ブランチはコミットにわかりやすい名前をつけたもの
  • rebaseしてもクソコミットは消えない