Git再学習

##趣旨
Git操作のミスをプロジェクトのソースコードのミスと履き違えることが度々あり、
今後このようなことのないよう、Gitの基礎から振り返ることにしました。

##Gitとは = バージョン管理システムのひとつ
バージョン管理システムは、大きく2つに別れる。
「集中型バージョン管理システム」と、「分散型バージョン管理システム」。
大きな違いは「リポジトリが単一」か、「リポジトリが複数」か。

###集中型バージョン管理システム
SVN
リポジトリが一つのみ。
同時に複数人が作業できないため、作業中は他の人が触れないよう、ロックする。

###分散型バージョン管理システム
Git
Linux のカーネル開発のために 2005年にリーナス・トーバルス氏が開発。
CVS や Subversion などの中央管理型 (Centralized) のバージョン管理システムと違い、リポジトリを複数持つことを前提とした分散型のバージョン管理システム。

参考：
Git　- 分散型バージョン管理システム
http://linux.keicode.com/prog/git.php

参考：
ガチで5分で分かる分散型バージョン管理システムGit
なぜ必要か。集中型と分散型の違い
http://www.atmarkit.co.jp/ait/articles/1307/05/news028_3.html

###リポジトリ
「ファイル」や「ディレクトリ」の状態を記録する場所。
保存された「ファイル」や「ディレクトリの状態」は、内容の変更履歴として格納される。（変更履歴＝差異のみ保存（蓄積）される）

Gitを変更履歴を管理したいディレクトリをリポジトリの管理下に置くことで、
Gitが置かれたディレクトリ内のファイルやディレクトリの変更履歴を記録することが出来る。

###リモートリポジトリ
専用のサーバーに配置し、複数人で共有するためのリポジトリ。

>リモートリポジトリとは、インターネット上あるいはその他ネットワーク上のどこかに存在するプロジェクトのことです。複数のリモートリポジトリを持つこともできますし、それぞれを読み込み専用にしたり読み書き可能にしたりすることもできます。

参考：
Git の基本 - リモートでの作業
https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%81%A7%E3%81%AE%E4%BD%9C%E6%A5%AD

###ローカルリポジトリ
作業者が自分の手元のマシン（ローカル環境）に配置するリポジトリ。
一般的に作業メンバーの数だけ複数存在する。

###コミット【commit】
ファイルやディレクトリの追加や変更をリポジトリへ記録するには「コミット」という操作を行う。
コミット実行時には、コミットメッセージの入力が求められるが、必須ではない。
コミットには英数字40桁の「コミットID」が割り振られ、このIDを指定することでリポジトリの中からコミットを指定することが出来る。

###ワークツリー（ワーキングツリー）
実際に作業しているディレクトリのことをワークツリー（またはワーキングツリー）と呼ぶ。
リポジトリとワークツリーの間には「インデックス」が存在する。

※コマンドで `git worktree` を使うと、一つのローカルリポジトリで作業ツリーを複数同時に持てる。
参考：
git worktreeを使ってみる
https://qiita.com/yoichi22/items/8f92110f24690ca8966f

###インデックス【index】 （ステージ【stage】）
リポジトリにコミットする準備をするための場所。
ここへ変更内容を保存することを一般的にステージングと呼ぶ。

Gitでは、コミットを実行したときのステージングされた状態（履歴）のみを記録するので
まずインデックス（ステージ）へ変更内容を登録する必要がある。

インデックスをリポジトリとワークツリーの間に挟むことで、ワークツリー内の必要ないファイルを含めずにコミットを行ったり、ファイルの一部の変更だけをインデックスへ登録してコミットすることが出来る。

【自分用の注意点】
「インデックス」または「ステージ」。
コマンドに置き換えると、git add（ファイルやディレクトリをインデックスに登録）。
VSCodeではgit画面、SourceTreeでは「ファイルステータス」画面から、変更ファイルにチェックを入れると「ステージング」など表記される。これが「インデックス」（またはステージ）に上がった状態。

参考：
Git初心者に捧ぐ！Gitの「これなんで？」を解説します。
http://kray.jp/blog/git-why-explanation/

###プッシュ【push】
コミットした内容をリポジトリへアップロードすること。
プッシュすると、リポジトリへ自分の変更内容（変更履歴）がアップロードされる。

一般的に、ローカルリポジトリからリモートリポジトリへプッシュすると、リモートリポジトリ内の変更履歴がローカルリポジトリの変更履歴と同じ状態になる。

###クローン【clone】
リモートリポジトリを複製すること。
クローンを実行すると、変更履歴を含むリモートリポジトリの内容を丸々ダウンロードされ、ローカルリポジトリとして作成される。

【自分用の注意点】
クローンを行うことで、クローンを実行したPCに「ローカルリポジトリ」が生成される。
masterブランチの最新のプログラムソースだけが複製されるわけではなく、「ローカルリポジトリ」なので、変更履歴（gitlogやブランチ）もすべて含まれる。
他のリポジトリと同様にGitの機能が使える。

###プル【pull】
リモートリポジトリからローカルリポジトリを更新するには「pull」（プル）を行う。
pullを実行すると、リモートリポジトリから最新の変更履歴をダウンロードし、自分のローカルリポジトリにその内容を取り込む。

一般的には、引数に「リモートリポジトリ」と「ブランチ」を指定する。
 `git pull <remote> <branch>`

参考：
サルでもわかるGit入門〜入門編〜
https://backlog.com/ja/git-tutorial/intro/

pullを実行すると、リモートリポジトリから最新の変更履歴をダウンロードしてきて、自分のローカルリポジトリにその内容を取り込む。

pullは【fetch + mergeを同時に行うこと】。

pullは【git fetch】と【git merge origin/master】を全部まとめてやってくれる。
ただし、mergeしたくない時に実行すると余計なコードが反映されてしまうので注意する。
もし実行してしまった場合は、戻したいコミットのIDを調べ、git reset --hard IDで元に戻せる。

###フェッチ【fetch】
fetchはリモートリポジトリの最新の状態を取り込む（保存や上書きはしない）。
リモートリポジトリから最新のデータを持ってきて、ローカルリポジトリ内のリモートブランチに反映する。

###マージ【merge】
mergeは異なる作業ブランチを統合させること。

git fetchした後で、git merge origin/masterすると、ローカルリポジトリ内のmasterブランチに、origin/masterの内容が反映される。
コンフリクトがある場合は、このタイミングでコンフリクトが発生する。