Git

Git がもっとよく分かる! [01] コミット・ブランチ


このドキュメントについて


想定読者


  • 現在 Git を勉強中の人

  • Git を雰囲気で使っている人


    • 特に「この状況のときにはこのコマンドを打てば良い」的なおまじないを丸暗記して付け焼き刃的に活用している人




目的


  • Git の各操作(チェックアウト・フェッチ・マージ・プッシュなど)を行うと, リポジトリの中で何がどのように変化するのか頭の中でイメージできるようになる


    • その結果, 複雑な操作もおっかなびっくりではなく自信を持って使いこなせるようになる



  • 色々な局面で, アドリブな応用操作が臨機応変にできるようになる


免責事項


  • Git をある程度かじったことのある読者を対象としているため,新出の Git 用語が断りなく出現することがあります

  • 「頭の中でイメージできるようになること」をゴールとしているため, ある程度厳密さ・正確さを犠牲にした内容となっています. 正確な情報については Git の公式マニュアル など, 信頼あるソースを参照してください

  • 「中身が抽象的すぎてよく分からない」という方は, まずはその他の初心者向けテキストで一通り学習いただくことをオススメします





「コミット」と「ブランチ」

今回は, 「コミット」と「ブランチ」の概念についておさらいしていきます.


更新履歴を「串団子」として表現する

そもそも「バージョン管理」とは, コンピューターで扱うあらゆる電子データの「更新履歴」を記録するための仕組みです.

例えばソフトウェアのソースコード・WEB サイト・書籍の原稿・論文・イラストなど, 様々なコンテンツがバージョン管理の対象となりえます.

Git-basic01.png

Git に限らず, 各種バージョン管理システムでは更新履歴を串団子状の図であらわすことがよくあります.

このドキュメントでは以下のような更新履歴の図のことを 「串団子」 と呼ぶことにします.

Git-basic02.png


コミット = 団子を追加すること

Git で何かのコンテンツの履歴を更新するとは, 言い換えると串団子の先端に団子を付けていくことと言うことができます.

串団子に団子を追加する行為を 「コミットする」 あるいは単純に 「コミット」 と呼びます.

Git-basic03.png


ブランチ = 追加可能な串団子

串団子の中には, 串の先端に新しい団子を追加できるものと追加できないもの 1 があります. 追加できるタイプの串団子のことを 「ローカルブランチ」 あるいは 「ブランチ」 と呼びます.

このドキュメントでは, とある串団子が追加可能である(=ローカルブランチである)ことを, 串の先端が団子の先まで伸びているかどうかで表現することにします.

Git-basic04.png

今まで Git や Subversion などなんらかのバージョン管理システムを触ってきた読者の中には, 「ブランチ」 (branch) というと英語の意味の通り木の幹から伸びている各枝の部位を想像する方も多いと思います. このドキュメントを読み進めるにあたってそのようなイメージは一旦忘れて, 「ブランチ = 串団子」 をイメージするようにしてください.

串団子の根本から先端まで, すべて含めてひとつのブランチです.

Git-basic05.png


ブランチの複製

Git ではリポジトリ内のあらゆる串団子を複製 2 することができます. 串団子の複製をつくることを 「ブランチを作成する」 あるいは 「ブランチを切る」 などと表現します. (図1)

複製元の串団子の種類に関わらず, 複製後は必ずローカルブランチとなります. もしも複製元がコミットできないタイプの串団子でも, 複製後はコミットできるようになります. (図2)

Git-basic06.png

ブランチを複製することで, 元のブランチと複製後のブランチのそれぞれに対して異なるコミットを追加していくことができます. Unix や Linux に詳しい方にとっては, 「プロセスのフォーク」に似ていると言うと分かりやすいかもしれません.

Git-basic07.png


中級者向け tips: バックアップとしての新規ブランチ

現在参照しているブランチで git rebasegit reset --hard といった破壊的操作を行う場合に, 事前に 「バックアップ目的でブランチを切っておく」 という習慣をつけておくと安心して作業ができます.

「ブランチ作成」が「ブランチ複製」と同義であることを利用した応用例と言えます.

例えば master ブランチの履歴を git rebase で改ざんしたい場合

git branch master-backup # master-backup という名前で現在の master ブランチの履歴を残しておく

git rebase -i hogehoge # なんらかの破壊的操作を実行

もしも rebase の結果がおかしくなって, 元の状態に戻したくなったら

git reset --hard master-backup # master ブランチをバックアップの状態に戻す

git branch -d master-backup # バックアップに取っておいたブランチを削除する

で簡単に元に戻すことができます.

リモートブランチを force push で書き換えたい場合も, 念のためバックアップ用のブランチを事前に push しておくと良いでしょう.


リポジトリ = 串団子の集合体

とあるタイミングで串団子が複製され, 複製された串団子からさらに新しい串団子が生まれ, ……という具合に串団子の複製が繰り返されると, リポジトリの中が串団子で一杯になっていきます. (Unix がただ一つの親プロセス init を起点にして, 子プロセス, 孫プロセスへとフォークを繰り返してたくさんのプロセスが生まれていくのに似てますね)

多くの方は「リポジトリ」という概念について, ひとつの枝が途中でどんどん分岐していくような木構造のモデルを思い浮かべるのではないかと思いますが, そうではなく「リポジトリ=串団子の集合体」としてイメージする癖をつけておくと, 今後いろいろと応用が効くようになります.

Git-basic08.png


まとめと次回予告

コンテンツの更新履歴を「串団子」に例えて, その性質を以下のようにまとめました.


  • 串団子の先端に新しい団子をつけていくことを 「コミットする」 あるいは 「コミット」 と呼ぶ

  • 串団子には, 先端に団子を追加できるタイプとできないタイプがある


    • 団子をつけられるタイプの串団子を 「(ローカル)ブランチ」 と呼ぶ



  • どんな串団子も自由に複製ができる



    • 「ブランチを作成する」 , 「ブランチを切る」 という操作は, 任意の串団子を複製することに等しい

    • すべての串団子は複製後にローカルブランチとなり, 新しい団子を自由に追加していけるようになる



  • 「Git リポジトリ = 串団子の集合体」と捉えることができる

実は今回取り扱わなかった串団子の性質として, 「串が途中で2股以上に分岐したり, 2本の分岐がひとつに合流したりする」 というものがあります. 詳しくは第2回「マージ」編で解説します.





  1. (中級者向け解説) 追加できないタイプについて, 具体的にはコミット ID やリモートブランチなど, チェックアウトすることで detached HEAD な状態になるものを想定しています 



  2. 「複製」といってもファイルシステム上のファイルコピーと異なり, とあるオブジェクト (コミットの実体) に複数の参照を付与するだけなので, 極めて低コストな処理です