脱初心者:Gitについてもう一度知る
はじめに
この記事を読んでいる方は、Gitをなんとなくで使っている方でしょう。
そんなあなたはどんなコマンドを使うにも恐る恐る使っていて、やらかすのが怖くてたまらないことでしょう。
もしくはなんとなくGitを使っていて嫌な気持ちになっていませんか。
この記事は、そんなあなたに向けてコマンドについてではなく、Gitの内部構造にフォーカスして図解していきます。
そもそもOneDriveとかでファイル共有するのはダメなの?
ダメです。
ダメなところは3つあります。
それは
- 他人の作業を上書きしてしまう
- バージョン管理がしづらい
- 前のバージョンに戻せない
の3つです。
ではAさんとBさんがOneDriveでゲームを作っているとしましょう。
共有ファイルでの作業
こんな感じで作業を表現してみましょう。
話を簡単にするために、1人につき1日1回だけ作業できるとします。
AさんもBさんも、1日に1つだけ作業を進めることができます。
順番にAさんとBさんが作業していていい感じ
AさんBさんが交互に作業していて、今のところいい感じのように見えます。
他人の作業を上書きしてしまう
しかし!
AさんとBさんが同じ作業をベースに作業してしまった
あーっ!AさんとBさんが同時に、2をベースに3の作業をしてしまいました!
このままOneDriveにアップロードすると...
Bさんの作業はAさんの作業をベースにしていないからAさんの作業が消えてしまった
Aさんの作業をBさんの作業が上書きしてしまいました!
なぜならAさんとBさんは作業中の内容を共有していないので、BさんがアップロードしたファイルにはAさんの作業内容が入っていないからです!
それをアップロードしてしまうとAさんの作業は丸々上書きされちゃいますよね。
つまり、2人が同時並行で作業を進めることができません!!!
それって...本当に複数人開発なんですか...?
バージョン管理がしづらい
さらに、もしBさんが作業1をベースに作業をしている途中に、Aさんが作業2と3をしたとします。
ここでBさんが作業2と3を適応し忘れて、作業1をベースに作業3をしてしまうと...
さらに作業1をベースに作業しているとき
作業3どころか作業2も台無しに
ここから先、作業2と3がなかったことになってしまいます。
つまり、Bさんはどれだけ作業の途中でも、Aさんが作業をしたらそれの変更点を教えてもらって、自分のファイルと比較して、適応して...ってしなきゃいけないわけです。
しかし! 少ないファイル数ならまだしも、プロジェクトの規模が大きくなって、10人20人で開発したり、ファイル数が100や1000にまでなってしまうと... 絶対にまともに作業できないですよね。
前のバージョンに戻せない
さらにさらに、
ファイルを上書きしているので前の状態に戻せない
これでは一度変更してしまうと、前の作業に戻ることができません!
どんなにやらかしても、上書きしてしまうともうそれまでなんです。
ということで、OneDriveのようなファイル共有サービスで開発をするのはやめましょう!!!
これらの話は、こちらのブログを参考にさせていただきました。
Gitについて
では、いよいよGitについてです。
その前に、GitとGithubの違いについてはご存じでしょうか。
そもそも、Gitには2つの主な機能があります。それは下記の二つです。
- ソースコードを変更した履歴を見たり管理する
- 複数人開発のときにソースコードを管理する
ソースコードを変更した履歴を見たり管理することはGitの機能です。
そして、複数人開発のときにソースコードを管理することは、GitとGithub両方によって提供される機能です。
これらの違いについてはリポジトリ(repository) について知ることで理解が深まります。
コミットとは
リポジトリについて知る前に、コミット(commit) について理解する必要があります。
コミット とは、Gitにソースコードなどの変更を保存する動作のことです。
具体的にコミットとは、
- 変更の内容の説明
- 変更をした人
- 日時
- 変更した作業のID
- どの変更から派生したのか
- どのファイルをどう変更したのか
という内容の塊であるコミットオブジェクト(commit object) を作り、Gitに保存することを言います。
コミットの流れ
つまり、作業をした人はコミットをすることで変更を保存します。
Gitでは、これらのコミットオブジェクトたちを繋いで、作業の履歴として扱います。
つながれたコミットオブジェクト
すべてのコミットは、すべてその前の履歴から派生しています。
なので、最新のコミットは過去の作業をすべて反映した状態になっています。
そして、Gitではコミットオブジェクトとソースコードなどのファイルをこんなかんじで大量に保存しています。
Gitのたくさんのコミットオブジェクトとファイルたち
これらのコミットオブジェクトやファイルなどを保存する場所をリポジトリ(repository) というんです!
そして、Gitはコミットオブジェクトを大量に保存することで、過去の変更の内容を参照したり、他の変更と比較したりすることを可能にしているんです。
これらの過去の変更の参照と差分を見れる機能はGitの最も重要な機能です。それを実現するのがコミットオブジェクトってわけです。
リポジトリとは
先ほど説明した通り、コミットオブジェクトやファイルなどを保存する場所がリポジトリです。
つまり、過去の変更の塊をリポジトリと呼んでいます。
さらにこの中で、PCのようなローカル環境にあるリポジトリをローカルリポジトリといいます。
作業をする人は、自分が編集したファイルからコミットオブジェクトを作り、それをローカルリポジトリに追加します。
ここまではGitの機能です。
そしてGitでは、このローカルリポジトリをインターネット上に存在するリモートリポジトリに共有することができます。
リモートリポジトリとローカルリポジトリの関係
こうすることで、互いのPCにあるコミットオブジェクトとファイルを、リモートリポジトリ経由で共有するわけです。
そして、Githubはリモートリポジトリであり、それを管理するサービスなんです!
これらの機能を使うことで、作業の内容と履歴を複数人で共有することができます!
さらに、もし仮に誰かのPCが壊れたり、Githubがサービス終了してしまっても、どれか1つでもリポジトリが残っていればそれを共有することで復旧できます。
ブランチとは
これでコミットオブジェクトをリモートリポジトリ経由で経由で共有できるようになりました。
しかし!先ほどのOneDriveの例で起きた、他人の作業を上書きしてしまう問題はまだ解決していません。
そこで、ブランチ(branch) という機能を使うことでこの問題は解決することができるんです。
ブランチとは、作るものごとに作業場所を分けるような機能です。
ブランチ増殖
JumpとMoveという名前でブランチを作ると、コミットオブジェクトの左上に吹き出しのようなものができました。
この吹き出しは参照(ref) といいます。
参照は各ブランチの最新のコミットを表しています。
MoveやJumpのブランチでコミットをしてみると・・・
作業で枝分かれしたブランチ
ブランチが枝分かれしました!
これで、互いの作業をうまく干渉しないように進めることができました!
マージとは
ですが、このままではお互いの作業は別のブランチにあり、どちらも互いの内容を反映していません。
ここで登場するのが、マージコミットです。
マージコミットとは、その名の通りブランチ同士を融合するコミットです。
試しにMoveとJumpのブランチを融合してみましょう。
結果、MoveとJumpをマージすることで、コミットC1が作られました。
Gitでは、マージコミットをすることでそれぞれの変更点をいい感じに組み合わせた最新のコミットを自動的に作ってくれます。
ブランチの参照の位置も最新のC1になっていて、完全にA1とB1が融合したのがわかります。
C1の参照元も、A1とB1の2つになっています。
コンフリクトとは
では、こんな時はどうしましょう?
MoveとJumpが同じところに違う変更をしている
MoveとJumpで、同じ重力に対して変更をしています。
このままマージしようとするとどっちを変更として適応すればいいかわかりません!
この状態をコンフリクト(conflict) といいます。
さらに、コンフリクトしているときはマージしないほうがいいのでコンフリクトをなくす必要があります。
本来は面倒なこの作業をGitは簡単にしてくれます!
Gitでは、コミットオブジェクトに変更の差分が保存されていますよね。
なので、コンフリクトしている場所がわかり、簡単になくすことができます!
コンフリクトを解消することで・・・
コンフリクトを解消したらマージできた
この通り、無事にブランチをマージすることができました!。
コンフリクトを解消する方法はいろいろあるので、具体的な方法は今回は割愛します。
Gitを使った作業の流れ
作業の流れとしては、
まず作業をしてインデックスという場所に入れます。
その後に、インデックスにあるファイルからコミットオブジェクトを作ります。
そして作ったコミットオブジェクトをローカルリポジトリに保存して、
リモートリポジトリに共有します。
そこから、ほかの開発する人が自分のローカルリポジトリにリモートリポジトリの内容を持ってくると・・・
作業フォルダに適応できます!
まとめ
いかがだったでしょうか。
今回の内容をまとめると、
- OneDriveなどで複数人開発するのは危険
- Gitを使うと便利
- コミットで作業の内容を管理できる
- リポジトリに保存することで作業を共有できる
- ブランチで複数人開発がスムーズにできる
- コンフリクトが起きても簡単に解消できる
です。
そして、皆さんが悪戦苦闘しているGitコマンドは、これらのコミットオブジェクトやブランチ、リポジトリを操作するためのコマンドなんです!
これらの内容はGitオブジェクトやGitコマンドなどの単語で調べると詳しい内容が出てくると思います。
今回の記事で気になった方やもっと詳しく知りたい方はぜひ調べてみて下さい!
それではみなさん円満なGitライフを~
参考にさせていただいたサイト
Discussion