これだけは押さえておきたいGitの仕組み

# こんな人が対象
- 職場のソース管理がGitになったが今だに操作方法がよく分からず、  
  毎回詳しい人に聞かないとソースを上げられない
- 何だかSourceTreeにすぐ怒られる
- 何だかSourceTreeの線がすぐぐちゃぐちゃになる
- ネットで調べても丸を線でつないだ絵とかコマンドの説明ばかりで  
  どうすればいいのか分からない

# Gitは基本的な仕組みを押さえれば、実はそんなに難しくない(かも)
- 以下の説明は簡単のために細部を思い切ってはしょっているので、  
正確でない記述も含まれています

# Gitが管理しているのはこの3つだけ
1. コミット
2. タグ
3. ブランチ

## コミット
- SourceTreeの画面に出ている◯の１つ１つがコミット
![commit](https://qiita-image-store.s3.amazonaws.com/0/29853/1b0957dc-af99-8581-4ab5-4f1a8792bbe3.png)

- コミットは以下の情報を1つの圧縮ファイルにまとめたようなもの
    * 変更されたファイルの中身
    * 作成者や作成日
    * コミットメッセージ

- 別のコミットを親として持つのが特徴

- 空のリポジトリに最初にソースをインポートしたときだけ、親のないコミット(1)ができる

![img1](https://qiita-image-store.s3.amazonaws.com/0/29853/27807a82-8f3c-c57c-3908-2e510d3bfbc4.png)

- その後ソースを変更してコミットすると、(1)を親にした新しいコミット(2)ができる

![img2](https://qiita-image-store.s3.amazonaws.com/0/29853/dd0f983c-8f3f-741f-67d8-54a824fc6cdd.png)

- これを繰り返すと、◯を線でつないだ図形が伸びていくような感じになる(コミットグラフ)

![img3](https://qiita-image-store.s3.amazonaws.com/0/29853/c8c9f447-8631-16f7-b579-0055d04935e0.png)

- グラフ上の任意のコミットを選んで、その時点のソース全体のスナップショットを取り出すことができる(チェックアウト)

## タグ
- コミットにはそれぞれコミットIDというのが振られている
    * 1ad1cb6e68271f275c331d7c8571449f3c0addb4 <- こんなやつ

- Gitのコマンドでコミットを操作するときにこのIDを指定する

- コミットIDは覚えられないし、操作の都度IDを調べるのもしんどい

- そこで意味のあるコミットにはタグで別名をつけて、
コミットIDの代わりにタグ名でも指定ができるようになっている

![img11](https://qiita-image-store.s3.amazonaws.com/0/29853/eee0341d-25c2-2717-6a92-0fbd934669f1.png)

- リリースした時にバージョン番号をタグ付けしておいて、  
  あとで「このリリースではどうなってたっけ？」なんて調べたりするのに使う


## ブランチ
### 基本
- ブランチの実体はタグと同じで、コミットに別名を付けている

- タグとの違いは、位置が移動するということ

- 空のリポジトリに最初にソースをインポートすると、
    * masterというブランチが自動的に作られる
    * masterは最初のコミット(1)を指している

![img4](https://qiita-image-store.s3.amazonaws.com/0/29853/8cad9448-a53a-30f1-a0ee-7a4aaf04b21b.png)

- その後ソースを変更してコミットすると、
    * 新しいコミット(2)ができる
    * masterの位置が移動して、(2)を指すようになる

![img5](https://qiita-image-store.s3.amazonaws.com/0/29853/e2918f50-7f7a-a5df-7e86-cf05493e5b30.png)

- これを繰り返すと、コミットグラフは伸びていき、masterは常にその先端を指している感じになる

![img6](https://qiita-image-store.s3.amazonaws.com/0/29853/1c1d1070-86ff-5c4d-8dc3-475916c3defe.png)

### 分岐
- 新しくブランチhogeを作ると、
    * hogeは現在のコミット(4)(masterと同じ位置)を指す
    * ここからはブランチをチェックアウトで切替えて、  
      hogeで作業したりmasterに戻ったりすることができる

![img7](https://qiita-image-store.s3.amazonaws.com/0/29853/c2d91d4f-992e-d9c3-9702-03d0f00b133e.png)

- hogeで作業して変更をコミットすると、
    * (4)を親にした新しいコミット(5)ができる
    * hogeは(5)に移動する
    * masterの位置は(4)のまま

![img8](https://qiita-image-store.s3.amazonaws.com/0/29853/4d2344d5-20c2-02e4-84ee-f45fc3b414c5.png)

- ブランチを切替えてmasterに戻ってくると、
    * ソースは変更する前の状態(4)に戻る

- masterで作業して変更をコミットすると、
    * (4)を親にした新しいコミット(6)ができる
    * masterは(6)に移動する
    * ->コミットグラフが枝分かれする

![img9](https://qiita-image-store.s3.amazonaws.com/0/29853/45020e73-20c1-512f-b932-8198220f3524.png)

- ブランチを再度hogeに切替えた場合は、ソースは(5)の状態になる

- hogeはmasterに影響を受けずに、masterはhogeに影響を受けずに、
  それぞれ開発を進めることができる


### マージ
- ブランチでの開発が終了したら、通常は分岐元にその変更を反映する(マージ)

- hogeをmasterにマージした場合、
    * hoge(5)とmaster(6)の親をそれぞれ辿っていき、共通の親(4)を見つける
    * (5)と(6)の2つを親に持つ新しいコミット(7)が作られる
    * (7)は(4)->(5)の変更と(4)->(6)の変更を両方含んだものになっている
    * masterが(7)に移動する

![img10](https://qiita-image-store.s3.amazonaws.com/0/29853/7daf73b7-4ee0-28ed-d23a-b88094a86576.png)


# 実物を見て確認
![stuff1](https://qiita-image-store.s3.amazonaws.com/0/29853/ca7df7f9-5121-3e3d-355e-7b05f4973b7e.png)
![stuff2](https://qiita-image-store.s3.amazonaws.com/0/29853/c3e6c948-bd34-6396-2194-e892a737bd7e.png)

1. .gitフォルダ
    - ローカルリポジトリはこの中にある
2. 作業コピー(ワーキングツリー)
    - ローカルリポジトリからコピーされたソースが展開されている
    - ブランチをチェックアウトすると、そのブランチのソースにまるごと置き換わる
3. .git/objectsフォルダ
    - コミットの実体(変更されたファイルを圧縮したようなもの)が入っている
4. .git/refsフォルダ
    - タグとブランチのそれぞれについてファイルが作られている
    - ファイルの中には現在指しているコミットのIDが書かれている
5. .git/index
    - インデックスとかステージング領域とか呼ばれている
    - コミット対象のファイルをステージしたときに、ファイル名などがここに書き込まれる


# 無理やり3行にまとめてみる
- Gitにソースを入れると、◯ができて、他の◯と線でつながる
- Gitは◯を線でつなげて履歴を管理している
- 線は枝分かれさせたり、まとめたりできる

# こちらもどうぞ
- [もう少し押さえておきたいGitの仕組み(リモート編)](http://qiita.com/nejiko96/items/bf9884e0e4e6485327e8)
- [SourceTreeに怒られたときの対処方法](http://qiita.com/nejiko96/items/bb99f7b5f6541ec096e9)