この記事について
この記事は、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
で変換して話を進めたいと思います。
魚を釣った人の選択肢は2つ。そのまま河にリリースするか、クーラーボックスに入れて家に持ち帰るかです。
ここで、あなたが河釣りをする主な目的は、かっこいい魚拓をとること(注意:htmlの話とは全く関係なく、普通の魚拓です)。今日は、以前の魚拓よりもいい魚拓が作れそうな、sake.py
とmasu.py
を持ち帰る(ayame.py
を河に帰す)ことにしました。
ここで、魚拓に(commit
)したい魚(ファイル)を持ち帰る作業が git add
(いわゆるステージングというやつ)に該当します。
そしてあなたは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
)したくなる
ここまでの例え話は、自分の家にある魚拓、すなわちlocalレポジトリ内のみに限定していたお話でした。しかしこの世界には釣りをしている人はあなた以外にも複数人います。そうした人たちが、自分の釣った魚の魚拓を自慢する場所として、博物館の展示コーナーがあります。ここでは博物館が、remoteレポジトリに、展示コーナーがHEADポインタに相当すると考えてください。
さて、あなたが家にもっている手持ちの魚拓たちを、master河の上流にある、master
博物館(レポジトリ)に寄贈(git push
)するとします。今日釣った分に限定すると、sake.py
とmasu.py
の魚拓が博物館に送られます。しかし博物館には、すでにあなた以外の釣り師が寄贈したsake.py
の魚拓も届いておりました。博物館の展示コーナー(HEAD)として展示できるのは、一枚の魚拓だけです。こうして、どちらの魚拓を採用するかで衝突が起きることをconflict
と呼びます。conflictが起こると、ソースコード管理の観点から言うと、正確性や処理速度の観点から好ましいソースコードが選ばれます(魚拓の例はどうでしょう。思いつきませんでした)。こうして展示された魚拓は、あなた以外のその他の釣り人(開発者)も閲覧することができます。
複数の河(branch)で釣りをする
さて、この広い世の中に河は一つではありません。あなたは数ある川の中でも、全ての河の本流である、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をより深く勉強しようとするきっかけになることを、心から祈っております。