わかりにくいGitの仕組みを無理やり「河釣り」に例えてみた！

![fishing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494762/a34b7b06-94e3-cd56-c6a7-a65f4d7610b9.png)
# この記事について
この記事は、Gitの初心者向けに書かれたものです。`git add` -> `git commit` -> `git push` だけしか叩けなかった人が、差分確認の意義やブランチを切ることの重要性に気付くきっかけになればいいなと思って書きました。

Gitも河釣りも素人みたいなレベルの筆者ですので、間違った表現や、理解に苦しむ場所もあるかと思います。その際は遠慮なくコメントいただけますと幸いです。

釣り用語とGitの言葉の対応関係は、以下のようになっています。

```
釣り人 = 開発者
魚 = ファイル
河 = ブランチ
家 = localレポジトリ
魚を持ち帰る = add
魚拓をとる = commit
博物館 = remoteレポジトリ
魚拓を寄贈する = push
図鑑作成 = merge
図鑑 = 納品するソースコード
```

# 河釣りにおける `git add`と `git commit`
さて、釣り人(開発者)であるあなたは今日も、master河という名前の河に、魚釣りに出かけました。今日はたまたまサケ、マス、アヤメが釣れたようです。河釣りの話を無理やりGitの話に置き換えると、ここで言う**河**が**branch**に、そして**魚の名前**が**ファイル名**に相当します。pythonで開発するのに慣れている人は、`sake.py`, `masu.py`, `ayame.py`、javascriptで開発するのに慣れている人は、`sake.js`, `masu.js`, `ayame.js`などというように、適宜脳内変換して読んでいただけると理解しやすいかと思います。ここでは、筆者が主にpythonを使っていると言う理由から、魚のアルファベット表記+`.py` で変換して話を進めたいと思います。

![fishing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494762/900677e6-c85b-9edd-f8a9-b444d21477e8.png)

魚を釣った人の選択肢は2つ。そのまま河にリリースするか、クーラーボックスに入れて家に持ち帰るかです。

ここで、あなたが河釣りをする主な目的は、かっこいい魚拓をとること(注意:htmlの話とは全く関係なく、普通の魚拓です)。今日は、以前の魚拓よりもいい魚拓が作れそうな、`sake.py`と`masu.py`を持ち帰る(`ayame.py`を河に帰す)ことにしました。

ここで、魚拓に(`commit`)したい魚(ファイル)を持ち帰る作業が `git add`(いわゆるステージングというやつ)に該当します。

![魚拓.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494762/4e47b872-6d9b-a357-f64b-885e2a478a2d.jpeg "魚拓の例")

そしてあなたは`sake.py`と`masu.py`の魚拓をとることに成功しました。二匹とはいえせっかく苦労してとった魚です。**いつ、誰が、どう言う状況で魚(ファイル)を釣った(`add`した)のか**を、どこかに書き記しておきたくなるのが釣り好きの性でしょう。、あなたは釣りを行った状況を魚拓の脇(同じ紙)に書き記しておきました。こうして、魚の姿形の情報と釣りを行った時の情報が一枚になった魚拓が出来上がります。

この、**「釣りを行った時の情報付きの魚拓」**をとることが、`git commit` に該当します。
過去の魚拓が残っているので、今日釣った`sake.py`や`masu.py`と、以前釣った`sake.py`や`masu.py`とを比較(`git diff等`)することもできます。

ちょっとややこしくなってきたので、まとめると、**`add`は魚(ファイル)を釣って持ち帰る行為**、**`commit`は、釣った魚(`add`したファイル)の情報付き魚拓を取る**行為に該当します。

あたりまえですが、持ち帰った魚しか魚拓が取れないのと同じように、`add`した分のファイルしか`commit`されません(今回で言うと`yamame.py`は、魚拓が取れない)。また、釣った魚の情報が魚拓と一緒に長い間残っているように、今まで`commit`したファイルについては、その当時のソースコードと、メッセージや編集者を後から閲覧することができます。後から閲覧するというのが、`git show [commitID]`に該当します。


# 魚拓を博物館に寄贈(`git push`)したくなる
![博物館.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494762/2f2872f7-980d-b1a3-0ad0-6e11137aa9b0.png)

ここまでの例え話は、自分の家にある魚拓、すなわち**localレポジトリ内のみ**に限定していたお話でした。しかしこの世界には釣りをしている人はあなた以外にも複数人います。そうした人たちが、自分の釣った魚の魚拓を自慢する場所として、博物館の展示コーナーがあります。ここでは博物館が、remoteレポジトリに、展示コーナーがHEADポインタに相当すると考えてください。

さて、あなたが家にもっている手持ちの魚拓たちを、master河の上流にある、`master`博物館(レポジトリ)に寄贈(`git push`)するとします。今日釣った分に限定すると、`sake.py`と`masu.py`の魚拓が博物館に送られます。しかし博物館には、すでにあなた以外の釣り師が寄贈した`sake.py`の魚拓も届いておりました。博物館の展示コーナー(HEAD)として展示できるのは、一枚の魚拓だけです。こうして、どちらの魚拓を採用するかで衝突が起きることを`conflict`と呼びます。conflictが起こると、ソースコード管理の観点から言うと、正確性や処理速度の観点から好ましいソースコードが選ばれます(魚拓の例はどうでしょう。思いつきませんでした)。こうして展示された魚拓は、あなた以外のその他の釣り人(開発者)も閲覧することができます。

# 複数の河(branch)で釣りをする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494762/b6b3cf13-7cac-ea79-3710-0c5e2726b6d3.png)

さて、この広い世の中に河は一つではありません。あなたは数ある川の中でも、全ての河の本流である、`master`河と呼ばれる河で釣りをしていたのです。しかし、master河から分岐した河(branch)では、独自に進化をとげた、また形質の異なった魚(ファイル)たちが存在します。それらの魚拓をとるべく、あなたは`develop`河で釣りを行うことにしました。

こうして新しく釣った(`add`)したbranch河の魚(ファイル)たちは、魚拓をとられ(`commit`され)、branch河の魚拓コレクションとしてあなたの家(local)に保管していました。もちろん家(local)には、`master`河(branch)の魚(ファイル)と`develop`河(branch)の魚(ファイル)が別々に保管されています。ここで問題になるのは、`develop`河で釣った魚(ファイル)の魚拓を、どの博物館に寄贈するかです。もちろん、`master`博物館に寄贈(`push`)することもできますが、`develop`河(branch)の魚たちは独自の進化を重ねてきたものです。`master`博物館に寄贈するよりもさきに、`develop`河のほとりにある`develop`博物館に展示してもらうのが筋でしょう。

かくして、あなたは、`develop`河(branch)で釣った魚を、都度都度`develop`博物館に寄贈(`push`)していくこととなります。

# 展示物の中から図鑑をつくる(`merge`)
さて、`master`博物館の展示物と`develop`博物館の展示物(HEAD)には、各釣り人からの魚拓の寄贈(push)が集まり、いろいろな魚の展示物が揃っています。博物館としては、これらの蓄積された魚拓から、図鑑を作りたいと思ったり思わなかったりします。

しかし困ったことに、二つの河(branch)では魚たちが独自に進化を重ねてしまったため、魚拓の姿形がどうも噛み合いません。これは、**branchどうしがconflict**していることに該当します。ふたつの博物館は顔を合わせ、それぞれの持ち寄った魚拓から、似た部分を抽出かつ異なる部分を取捨選択しながら、それぞれの魚の図鑑を完成(`merge`)させていきます。

こうして、複数人の釣り人(開発者)が持ち寄った魚拓(`commit`)から各河(branch)を代表する展示物が作られ、各河(branch)の展示物から図鑑(納品するソースコード)という最終成果物ができあがります。



# 最後に
いかがだったでしょうか。初学者に取ってとっつきにくいGitの仕組みが、釣り人の気持ちになることで少しは理解しやすくなったでしょうか。

余計わかりにくくなってしまった人がいたら、この記事のことは全て忘れてください。きっとそんなあなたは体系的にGitを勉強した方が習得が早いと思います。是非下記の記事を参考にしてみてください。
https://qiita.com/HaraShun/items/222ce7e0008ce776271a

筆を置いて思うことは、釣りもGitもそんなに詳しくはないなぁということです。厳密な理解のためではなく、初学者が次のステップに進むためのイメージの補完程度に思ってください。また、表現や誤り等、気になる箇所がありましたら、後学のためにご指摘いただけますと幸いです。

この記事を最後まで読んでくれたあなたにとって、この記事がgitをより深く勉強しようとするきっかけになることを、心から祈っております。