【初心者向け】Gitってなに？①まず流れを理解する（コードなし）

shellに続き、初心者が頑張って理解していくノート的記事です。
GitHubが常識と化してきた今日この頃、チャレンジしてみたものの、そもそもGitってなんなのかわからないと使いこなせない、っていうか挫折すると思います。私はしました。
なので、起き上がってまずGitについて本当に一から理解を試みました。

***

## Gitって何？

Gitとは、**[バージョン管理システム](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)**のひとつです。
バージョン管理‥？ :open_mouth: 
バージョンすなわち変更履歴の管理です。

例えばなにかファイルの書き換えをするとき、元データを失わないためにどのような工夫をするでしょうか。ほとんどの場合、保存用にコピーを作成しておくというのが定番の方法だと思います。
ですが、誰しもこんな経験があるのでは。

 - 元データの保管が面倒
 - 'meeting_3月.txt'、'meeting_最新.txt'といった名前のデータが複数できてしまう
 - チームで触っていて、最後に書き換えたのが誰なのかわからない
 - 先輩も同時に編集していたのに、知らずにタッチの差で上書きしてしまった
 - 書き換えたよ～と言われても（あるいは自分でも）、どこを換えたかわからない
 - 何回か前の更新状態の方が良かった、戻したい…

ある～～～！！
こんな事態を解消してくれるのが**Gitというバージョン管理システム**です。


## Gitを使えばこんなに便利。

上のあるあるを全部解決します。


 - 更新履歴はGitに保存されるので、バックアップ用のファイルコピーが不要になる
 - ファイルを「いつ」「誰が」「どこを変更したか」という情報も記録できる
 - それにより、編集を重ねたファイルも過去のある状態に復元することができる
 - どこを変更したか、差のあるところを表示することができる
 - あるファイルを自分が開いたあとに誰かが編集をはさんでいた場合、
アップロード時に警告が出るので、知らないうちに上書きという事態を防ぐことができる


素晴らしいですね。最高です。
ちなみに**GitHub**は このGitの仕組みを利用したウェブサービスで、無料で自分の**コードやデータなどを保存**したり、**世界に公開して、他の人と一緒に書き換える**ことができます。


### 分散型バージョン管理システム

Gitは **分散型バージョン管理**という仕組みを利用しています。
**ローカル環境（自分のPC等）に変更履歴を含む完全なリポジトリの複製が作成される**という仕組みです。言い換えれば、それぞれのローカル環境をリポジトリのサーバーに見立てているわけです。
そのためGitでは、ローカル環境にも変更履歴を保存できる、すなわち**ネットワークに接続していなくても更新作業を行う事が出来ます**。
今までは**集中型**といって、サーバーにある一つのリポジトリを複数人で使用していたため、変更の整合やネットワークの問題もありました。分散型にはそのような心配はなく、近年GitおよびGitHubは開発者の重要なツールになっています。

この辺のしくみは今はさっと読みにして、最後まで読んでから再読頂いた方が理解しやすいかも。


## リポジトリ？

リポジトリとその使いかたについて。
### リポジトリとは
ファイルやディレクトリの状態を記録する場所です。**変更履歴**として保存されています。管理したいディレクトリをリポジトリの中に置くことで、そのディレクトリ内のファイルやディレクトリの変更履歴を記録することができます。
リモートリポジトリとローカルリポジトリの2種類に分けられます。

 - **リモートリポジトリ**：サーバに配置して複数人で共有する用。
 - **ローカルリポジトリ**：各人がそれぞれのPC上で使う用。

**普段の作業はローカルリポジトリ**を使って全て**手元のPCで**行い、それを**公開**するときは**リモートリポジトリにアップロード**します。また、リモートリポジトリを通してほかの人の作業内容を取得することもできます。


要は自分の編集したファイルをみんなで見られる場所にアップロードするという流れですね。



## 用語いろいろ

用語がたくさん出てくるので、混乱してしまいますが、ここでクリアにしておかないと進めるごとに理解ができなくなってきます :confounded:。
逆に用語と流れさえクリアにできれば、最初は意味がわからなかった本やネット記事もグンと理解できるようになるので :smile:、 最初のうちに理解しておくのが良いです。


用語の説明とGitの使いかたを並行して説明していきます。
前述の単語は*斜体*にしておくので、なんだっけと思ったら上を見てみてください。

### ワーキングツリー
実際に作業しているディレクトリのことです。

### インデックス
*ワーキングツリー*での編集を終えたら、*ローカルリポジトリ*へ保存したいですね。その際、一旦ここに登録します。*リポジトリ*に追加するにはこのワンクッションを挟まないといけないのです。面倒なようですが、これを挟むことで、変更した差分だけを登録することができる等、のちの管理が明確になります。（かなりかいつまんで言うと。）
というわけで、**インデックスに追加されただけの段階では、まだ*リポジトリ*には保存されておらず**、「次にこれを保存したいです」という状態のままを保持しています。


### コミット
*インデックス*に追加したファイルを自分の*ローカルリポジトリ*に登録します。すると、前回の更新から現在の状態の**差分**を記録した**コミット**と呼ばれるものが作成されます。
このコミットは、**履歴としてリポジトリに格納されていく**ので、過去の変更履歴や変更した内容を知ることができるようになっています。イメージとしては上書きみたいなかんじです。


### プッシュ
さあ、自分の*ローカルリポジトリ*の変更履歴をいよいよ*リモートリポジトリ*にアップロードして共有するぞ！そのために行うのが**プッシュ**(Push)という操作です。プッシュを実行すると、*リモートリポジトリ*に自分の変更履歴がアップロードされて、*リモートリポジトリ*内の変更履歴が*ローカルリポジトリ*の変更履歴と同じ状態になります。



### プル
*リモートリポジトリ*を共有して複数人で作業していると、みんなが*リモートリポジトリ*に*プッシュ*していきますので、自分の*ローカルリポジトリ*に、ほかの人が*プッシュ*した変更内容を取り込んで更新していく必要がありますね。それには**プル**(Pull)という操作を行います。
プルを実行すると、*リモートリポジトリ*から最新の変更履歴をダウンロードしてきて、自分の*ローカルリポジトリ*にその内容が取り込まれます。


### クローン
*リモートリポジトリ*を複製して自分の手元で作業をするために、**クローン**(Clone)という操作を行います。クローンすると、*リモートリポジトリ*の内容をまるまるダウンロードしてきて、自分のところに*ローカルリポジトリ*として作成できます。
例えばすでに進行中のプロジェクトに途中から参加する際などにクローンをします。
クローンした*リポジトリ*は変更履歴も複製されているので、元の*リポジトリ*と全く同じように履歴の参照や*コミット*をすることができます。


![alot.jpeg](https://qiita-image-store.s3.amazonaws.com/0/86088/beb2925c-7621-4a75-8a68-012029a83a88.jpeg)


たくさんの言葉が出てきますが、一つ一つを理解すれば複雑ではありません。


## 流れのおさらい

 1. 新規作成、もしくはリモートリポジトリからクローンして手元に自分のローカルリポジトリを作る。

 2. それを編集し、ローカルリポジトリにインデックスを経てコミットを作成。

 3. これまでの変更履歴をローカルリポジトリからリモートリポジトリにプッシュして、自分の変更をアウトプット。

 4. 他の人の変更をインプットするために、リモートリポジトリにプルをして変更履歴をダウンロード、自分のローカルリポジトリで編集を加え‥1へ戻る


っといった感じの流れになっております。

文中でも述べましたが、ここに書いたことだけでも理解できたら、色んな記事がぐんと理解しやすくなったので、頑張ればどんどん踏み込んでいけそうな気がしています :grin: 。


今回は流れを理解することに焦点を当てたのですが、実はまだまだいろんなことがあるようです。次回は実際に使用する観点で書いていきたいと思います。

何かありましたら、コメント頂けたら嬉しいです。