今度こそ挫折しない git 入門 第2回

こんにちは、バカンのソフトウェアエンジニアの垣野内です。

この記事は[バカン Advent Calendar 2019](https://qiita.com/advent-calendar/2019/vacan)の22日目の投稿です。
[前回](https://qiita.com/kakinouchi/items/be54d21adcac1debc0c0)に引き続きgitの入門記事をおとどけします！今回はブランチについての解説です。
ブランチは、覚えるコマンドは少ないのですが、慣れるのに少し時間がかかるかもしれません。

今回もこれでもかというくらいスクショをつけておきました！
コマンドでの入門をおすすめするのは、[第一回](https://qiita.com/kakinouchi/items/be54d21adcac1debc0c0)に述べた通りです。
「なんでコマンドなの？もう令和だよ？」と言いたくなる気持ちをグッとこらえて、コマンド練習までぜひ一緒にやってみてください！

# ブランチとはどんなものか
[前回のコマンド練習その1](https://qiita.com/kakinouchi/items/be54d21adcac1debc0c0#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E7%B7%B4%E7%BF%92%E3%81%9D%E3%81%AE1)のところで、`git log` というコマンドを使うことでコミットの履歴が見れることを確認しました。
↓再掲
![git_branch_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/8784027f-92bc-5fe2-e929-1607b41c32ab.png)


`git log --graph --all` というオプションをつけて実行すると、もう少しグラフィカルに見れます↓
(※ グラフィカルに見る方法はいくつかあります[^1])
![git_log_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/5c16457b-7fff-9044-e846-6543c2125f09.png)

コミット1つ1つがアスタリスク * で表され、それらがつながったグラフが左端に表示されました。
このグラフを**コミットグラフ**と呼びます。
(おそらく公式な用語となってるわけではないですが、よく使われる言葉です)

そして、ブランチとは、**特定のコミットからコミットグラフを枝分かれ(まさに”ブランチ”)させるための仕組み** です。[コマンド練習その2](https://qiita.com/kakinouchi/items/77632d1bcc19bff4b588#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E7%B7%B4%E7%BF%92%E3%81%9D%E3%81%AE2)のところで解説しますが、ブランチを作ったときのコミットグラフを先にお見せするとこんな感じになります↓
このコミットグラフを表示させ、そして理解するところまでが今回のゴールです！
![git_branch_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/daa6b855-8cee-eda4-c686-a2b8f4c33d45.png)


# ブランチを使うと何が嬉しいのか
大きく3つ嬉しいことがあると筆者は考えてます：

    1. 枝分かれさせることで(ブランチを作ることで)、”本流”の方にうっかり影響をあたえずにすむ
    2. 複数人で並行して作業ができる
    3. コミットのまとまりを作ることができる

※"本流"というのはあくまで比喩です。枝分かれの前の「木の”幹”」と言ってもいいでしょう。具体的にはコマンドのところで理解を深めてください！

よくわからない人も、やはりコマンドを叩いてみることでわかるかと思いますのでやってみましょう！

# コマンド練習その2
さて、まずはブランチの一覧を確認するコマンドからいきましょう。
「え？もうブランチがあるの？」と驚かれたかもしれませんが、実は、`git init`した時点で、`master`ブランチという名前のブランチがデフォルトで作られるのです。

### ブランチの一覧(`git branch`)
では、`git branch` とたたいてみましょう！
![git_branch_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/68e7d901-67d5-7619-2db7-73d4e5676fc7.png)
無事に`master`ブランチの存在が確認できたでしょうか？
`git log` のところですでに見えていた`HEAD -> master` の `master` とは、実は`master`ブランチのことだったんですね。(上図↑赤枠)

`HEAD` とは現在の作業ディレクトリのことです。(作業ディレクトリについては[第一回](https://qiita.com/kakinouchi/items/be54d21adcac1debc0c0) へ)
つまり、「現在の作業ディレクトリは master ブランチを向いていますよ」ということです。
(ここの説明はブランチを複数作ってみたら理解できると思うので、わからなくても先に進んでみてください！
操作的な理解のあとに意味的な理解がついてくると思います。)


### ブランチを新たに作る(`git branch <ブランチ名>`)

次に、ブランチを作ってみましょう。`git branch <ブランチ名>`で作ることができます。
ここでは、branch_test_1 というブランチ名にしてみます。つまり、`git branch branch_test_1` とたたいてみましょう！そして、もう一度`git branch`と叩いてブランチの一覧を確認しましょう！
<img width="729" alt="git_branch_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/eb6ebd6c-7cbe-29aa-3617-224045958630.png">
↑上のように、branch_test_1 というブランチが作成できたでしょうか？
左のアスタリスクは、「作業ディレクトリが現在いるブランチ」を表しています。
現在”いる”という表現がわかりにくいかもしれませんが、これも進めていくうちにわかるかと思います。


ここで、`git log --graph --all`も確認しておきましょう。
![git_branch_3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/10b6e5cb-e1c4-c8fe-fe50-b802a254916a.png)
赤枠の部分の表示が少し変わりましたね。
ブランチが２つあり、`HEAD`は依然 `master`ブランチを向いています。

### ブランチを切り替える(`git checkout <ブランチ名>`)

ブランチには「切り替え」という考え方があります。
今、`master`ブランチに”いる”ことを確認しましたが、**`branch_test_1`ブランチに”切り替え”てコミットをすることで、`master`ブランチの状態を全く汚すことなくファイルの変更をすることができます**。
(作業ディレクトリをまるっとコピーして、別名で保存して作業しているのと似ています。しかし、”本流”に合流させる時の作業がはるかに簡単です)

実際にやってみれば意味がわかるでしょう。
まず、`git checkout <ブランチ名>`とたたき、ブランチを切り替えます。今回は`branch_test_1` に切り替えたいので、`git checkout branch_test_1` とたたきます。
そして、`git branch`をたたき、切り替わっていることを確認しましょう！
<img width="737" alt="git_branch_4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/ce3b1a41-c490-f557-6100-dd005e3ba716.png">

↑上の図のようになったでしょうか？
ここで、`git log --graph --all`も確認しておきましょう。
![git_branch_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/40f1a9c1-2b2a-e501-c2b0-a6238727f028.png)
ブランチを切り替えたので、`HEAD` は`branch_test_1`ブランチを向いています。

### 切り替えたブランチでコミットしてみる

切り替えた`branch_test_1`ブランチにて変更を加えてみましょう！
[前回](https://qiita.com/kakinouchi/items/be54d21adcac1debc0c0)の復習ですが、**「変更して、add して、commit する」 という流れ**ですよ！
ここでは、”git third test on branch_test_1” という文字列を加えてみました。
![Screen Shot 2019-12-23 at 1.23.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/dc5389c7-7a23-f86d-bf4d-f0229419a2a5.png)

コミットまでやったら、再び`git log --graph --all`でコミットグラフを確認してみましょう。

![git_branch_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/6380ae9f-b206-d2ec-bf50-b8fad3c12b53.png)
`HEAD -> branch_test_1` のコミットは`master`ブランチのコミットよりも先にいますね。[^2]

もう一度何か変更を加えてみましょう！
ここでは、”git fourth test on branch_test_1” という文字列を加えてみました。
![Screen Shot 2019-12-23 at 1.39.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/8589ac17-424d-e709-f740-e3234d063739.png)

くどいようですが、コミットまでやったら、再び`git log --graph --all`でコミットグラフを確認してみましょう。

![git_branch_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/26b72fb4-350e-995f-6940-e17cd8f4eb3d.png)
`HEAD -> branch_test_1` がいるコミットがさらにさきに進んでいることがわかります。

### もとのブランチに戻ってみると...???

ここでもとの`master`ブランチに戻ってみましょう。`git checkout master`です。
そして、`git log --graph --all`を打ってみましょう。
![git_branch_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/0de12285-5eeb-32bf-bd48-a969f11ae7e6.png)
masterブランチに切り替えたので、`HEAD`の向き先が `master`ブランチを向きましたね。
ここで、変更を加えてきたファイルも見てみてください。
![Screen Shot 2019-12-23 at 1.46.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/8f1042ad-6a49-ef16-24ab-4459654c0709.png)
”git third test on branch_test_1” という文字列や ”git fourth test on branch_test_1”という文字列がきれいになくなっていませんか？
なくなっているのではなく、**作業ディレクトリがこの時のバージョンに戻った**のです！

これで、[ブランチの一覧](https://qiita.com/kakinouchi/items/77632d1bcc19bff4b588#%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%AE%E4%B8%80%E8%A6%A7git-branch)のところで説明した `HEAD -> master` の意味がわかったのではないでしょうか？
 また、[ブランチを新たに作る](https://qiita.com/kakinouchi/items/77632d1bcc19bff4b588#%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%82%92%E6%96%B0%E3%81%9F%E3%81%AB%E4%BD%9C%E3%82%8Bgit-branch-%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E5%90%8D)のところで説明した、「作業ディレクトリが現在いるブランチ」という説明もわかってきたかと思います。
ブランチを切り替えて作業をすることで、**別名フォルダや別名ファイルを作ることなく複数のバージョンを共存させることができる**のです！
そのため、複数人での並行作業もやりやすいということですね！

これで、[ブランチを使うと何が嬉しいのか](https://qiita.com/kakinouchi/items/77632d1bcc19bff4b588#%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8%E4%BD%95%E3%81%8C%E5%AC%89%E3%81%97%E3%81%84%E3%81%AE%E3%81%8B)のところのメリット1とメリット2についても回収したつもりです。(メリット3については最後に軽く触れます)

### もとのブランチでコミットすると...???

もとの`master`ブランチで１つコミットしてみましょう！
ここではtest2.txt というファイルを新たに作り、”git fifth test on master” という文字列を加えました。
![Screen Shot 2019-12-23 at 1.58.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/289aee78-0b57-b201-cd0c-dc4b849d6e1c.png)

コミットまでやったら、いつもどおり、`git log --graph --all`でコミットグラフを確認してみましょう！

![git_branch_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/70dc08e6-4845-0c0b-6a02-a35e9a04e0ab.png)

まさにツリーのようにブランチが生えているようすが表示されましたね！:tada::tada::tada:
これでgitのブランチに関しても入門できたと言ってよいでしょう！おつかれさまでした！

### マージ(概念だけ)
最後に、後回しにしていた[ブランチを使うと何が嬉しいのか](https://qiita.com/kakinouchi/items/77632d1bcc19bff4b588#%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8%E4%BD%95%E3%81%8C%E5%AC%89%E3%81%97%E3%81%84%E3%81%AE%E3%81%8B)のところのメリット3について軽く触れたいと思います。
すぐ上のコミットグラフにおける、`branch_test_1`ブランチでの２つのコミットを本流の`master`ブランチへ合流させることができます。これをマージと言います。
「`branch_test_1`ブランチを`master`ブランチにマージする」という言い方をします。
(gitにおけるマージには明確に方向があるということに注意。「AとBをマージする」のではなく、「AをBにマージする」という考え方です)

これによって、`master`ブランチに一気に2つのコミットが取り込まれ、masterブランチのtest1.txtにもも”git third test on branch_test_1” という文字列や ”git fourth test on branch_test_1”が現れるようになります！
そして、この2つのコミットを戻したかったら、このマージを取り消せばよいのです[^3]。

マージのコマンドについては、ググってぜひやってみてください！

---
おさらいです。以下のコマンドの操作とともに、ブランチの有用性が理解いただけたかと思います。
- `git branch`(引数なし)(ブランチの一覧を表示)
- `git branch <ブランチ名>`(ブランチの作成)
- `git checkout <ブランチ名>`(ブランチの切り替え)

# おわりに

git シリーズはこれでおしまいです。入門者の方が挫折しないよう、内容をしぼり、かつ丁寧なコマンドの解説を試みました。
もちろんこの2回の記事で紹介できてないコマンドもいくつもあるのですが、基本的な考え方が理解できれば適宜ググっていけるのではないかと思っています。


# 参考文献
- [入門Git](https://www.amazon.co.jp/dp/4798023809) 絶版となってしまったようですが、個人的にはとても好きな本です。合う/合わないがとてもはっきりわかれる本だと思います。
- [ Git の仕組み (1) ](http://koseki.hatenablog.com/entry/2014/04/22/inside-git-1) この記事を読んで Git って面白いなと思ったのでした。ものごとの仕組みに興味のある方は、コマンドに慣れてきたころに読んでみると面白く読めると思います。
- [サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)
- https://twitter.com/098ra0209/status/1163424568544907265 最近 twitter で見つけたものです。ポップな絵とともに用語の整理ができてよいですね。

# 参考リンク
- [株式会社バカン（Vacan, Inc.）](https://www.vacancorp.com/)
- [バカン (Vacan) Advent Calendar 2019](https://qiita.com/advent-calendar/2019/vacan)

[^1]: VSCode や IntelliJ などのエディタのプラグインを使うという方法、SourceTree などの git のGUIクライアントを使うという方法などです。ちなみに筆者は、以下のように、`git log --graph --all --format=\"%x09%C(cyan bold)%an%Creset%x09%C(yellow)%h%Creset %C(magenta reverse)%d%Creset %s\"` というコマンドを git の alias に登録して、`git tree`と打てばこれを呼び出せるようにしています。グラフィカルかつブランチが見やすいので気にいっています。`.gitconfig` というファイルがあると思うので、そこに全く同じように書けばよいです。![git_config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540893/37334359-0996-6734-7ed9-eb46f14510f5.png)
[^2]: 本編に書くか迷いましたが、git では、**コミットへの参照**という形でブランチが実現されています。コミットをするたびに、最新のコミットを追いかけていくので、動く参照です。
[^3]: gitは、マージも１つのコミットとして表現されます。マージを消すとはこのコミットを”取り消す”ということにほかなりません。さらについでに補足すると、git における「コミットんぼ取り消し」には2種類あります; 1.そのコミットをなくすというコミットをする(revert) 2.本当にそのコミットをなかったことにする(reset) それぞれググってみてください！