この記事のねらい
Gitが難しいという印象を持たれがちな理由は色々あると思いますが、そもそもGitが管理しているデータが何なのかさえ理解してしまえば、後の理解は芋づる式についてくる気がします。
なので、Gitのリポジトリを構成する最低限の要素を解説し、よく使うコマンドがどう作用するのかをまとめてみます。
次のような人におすすめです。
- Gitがいいらしいのは良く聞くけど難しそうで二の足踏んでる人
- Git使ってはいるけど分からないことが多くていつ事故を起こすか不安な人
- 中身がどうなってるか把握しないとスッキリしない人
最低限の要素は2つだけ
Gitのリポジトリはコミットとブランチでできています。これが分かればもうGitは8割方理解したも同然です。残りの2割はそれをどう操作するかという応用や組み合わせの話でしかありません。
コミット
次の3つの情報を持ちます。
- 変更内容(差分とログ・変更者の情報など)
- そのコミットであることを表すユニークなID(ハッシュコード)
- 親コミットのID
このコミットがたくさん積み上がることによってリポジトリは大きくなっていきます。
ブランチ
Gitにおいてブランチが持つ重要な情報はただ1つです。
- リポジトリの現在位置となるコミットのID
名前が付けられたりといった要素もありますが、本質的にはこれだけです。いわばコミットへのポインタです。
ブランチは必要に応じて自由に作成でき、1つのリポジトリ内に複数のブランチを持つことができます。その場合は、どれか1つのブランチを選択することでそのブランチが指し示すコミットが現在位置となります。
先に述べたように、個々のコミットは自分の親しか知りません。ブランチが現在位置となるコミットを指し示し、親コミットを再帰的に辿っていくことによって、そのブランチの系譜における全ての変更内容が把握できる仕組みになっています。
運用上は「ブランチの系譜に属するコミット全体」をブランチと呼ぶことも多く、それが混乱の一因となっている気がします。あくまでGitの管理上ではブランチはコミットへのポインタでしかないことを意識してみてください。
コマンドの作用をコミットとブランチの動きだけで解説
Gitのリポジトリに対する操作とは、突き詰めれば「コミットをどう増やして、ブランチをどう動かすか」でしかありません。名前が付いている操作も分解すれば粒度の小さい操作の集合だったりするので、実はそれほど覚えるべき事は多くないのです。
というわけで、よく使う&粒度が小さめの操作から解説していきます。
commit
現在のブランチが指すコミットを親とする新たなコミットを追加します。
ブランチは新たに追加したコミットを指します。
図ではコミットから伸びている矢印が下方向を指していますが、これはコミットが親方向への参照しか持っていないことを示しているためです。変更の時系列としては逆方向になります。
branch
新しいブランチを作成します。
デフォルトではリポジトリの現在位置を指す状態で作成されますが、既存のブランチ名やコミットIDを指定して作成することもできます。masterという名前のブランチは最初から存在しており、多くの場合はリポジトリの安定した状態を保持するために使われます。
branchコマンドでは作成のみを行い、ブランチの選択状態までは変更しません。
上図は、hogeブランチを新たに作成していますが、現在のブランチはmasterのままであることを表しています。選択状態を切り替えるには、後述するcheckoutコマンドを使用します。
checkout
現在のブランチを切り替えます。
切り替えるのと同時に、リポジトリ内の作業コピー(バージョン管理対象となっているファイル)の状態も変更されます。
ブランチを切り替えてコミットすることで、ツリーの分岐が発生します。コミットは現在のブランチが指すコミットを親とするからです。
(以下書きかけ)
このノリで書いてたら手間が大変なので挫折したのですが、この時点でもまぁまぁ価値がありそうなのでWIPで公開します。続きの需要がありそうだったら頑張ります。