GitとGitコマンド

## はじめに

**Git**とは、**ソースコードのバージョン管理システム**のひとつです。（**分散型バージョン管理**）

・更新履歴はGitに保存されるので、バックアップ用のファイルコピーが不要
・「いつ」「誰が」「どこを変更したか」という情報が記録され一目でわかる
・編集記録があるため、過去のある状態に復元することができる
・どこを変更したか、差分を表示することができる
・あるファイルを自分が編集している間に、誰かが編集を挟んでいた場合、アップ時に警告（コンフリクト）が表示されるので、知らないうちに上書きしてしまうという事態を防ぐことができる

といった感じの利点があります。

### 登場ブランチ
・master：リリース用の最新ソースのブランチ
・develop：開発用ブランチ
・work_develop：作業用ブランチ

## リポジトリ（repository）

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

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

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

## ブランチ（branch）

作業履歴を枝分かれさせて記録していくためのもの。
☆使うと何がいいの？？
　・他のブランチの影響を受けないため複数の作業を同時に進められる
　・作業単位で履歴を残すことで後で見た時にわかりやすい
つまり、複数人で開発するときにはそれぞれが他の作業者の影響を受けずに進めることができます。

### リモートブランチからローカルブランチを作成
```bash:
git checkout -b work_develop origin/develop
```
### 作成したローカルブランチをリモートに登録
```bash:
git push -u origin work_develop
```
### ブランチの一覧を見る
```bash:
git branch -a
```

## クローン（clone）

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

### リモートからクローンする

```bash:
git clone https://github.com/XXXX/XXXXXX.git
```
※https://github.com/XXXX/XXXXXX.git の部分はリポジトリのURL

## コミット（commit）

ファイルやディレクトリの追加・変更を、リポジトリに記録するには**コミット**という操作を行います。
その前段階として変更したファイルをインデックスに反映します。

### 変更をインデックスに反映⇒コミットする
ファイルの更新内容を、**インデックス**という「ひとまとめにしてコミットしたいファイルをとりあえず置いておくところ」に反映する操作を行います。(ステージといったりもします)
（1つ1つのファイルごとにcommitしてたら大変....）

```bash:
git add ファイル名
```
※ **git add .**　とするとローカルリポジトリ内の変更を一気にインデックスに反映できます。

git addしたファイルたちをコミットします。
コミットを実行すると、リポジトリ内では、前回コミットした時の状態から現在の状態までの差分を記録したものが作成されます。
このコミットは、時系列順につながった状態でリポジトリに格納されていて、最新の物から辿ることで、過去の変更履歴やその内容を知ることができるようになっています。 

```bash:
git commit
```
コミットの実行時にはコミットメッセージの入力を求められます。コミットメッセージは必須となっているため、空のままで実行するとコミットが失敗します。
コミットメッセージは、他の人がコミットの変更内容を調べる場合や、自分で後から履歴を見直す際に大切な情報となるので、変更内容のわかりやすいコメントを書きます。 

Gitでは標準的に
1行目 : **コミットでの変更内容の要約**
2行目 : **空行**
3行目以降 : **変更した理由**
という形式でコメントを書きます。

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

```bash:
git push origin master
```
git pushのあとのorigin masterというのはoriginというリモートリポジトリのmasterというブランチにプッシュするという意味です。

もし、ローカルの履歴がリモートの履歴とコンフリクトする場合、エラーになりpushは失敗します。

## コンフリクト（conflict）
ローカルの履歴がリモートの履歴とで編集が**競合**したときに発生します。

```bash:
# ブランチをdevelopに切替
git checkout develop

# リモートの状態を反映させて最新にするためにpullする
git pull origin develop

# 作業ブランチに切替
git checkout work_branch

# developをマージ
git merge develop
※「CONFLICT (add/add): Merge conflict～」というエラーが出る

# 状態を確認する
git status
```
すると、コンフリクトを起こしたファイルが表示されるので、そのファイルを修正します。
（私はエディタは、**Visual Studio Code**を普段使用しているのですが、コンフリクトが起きた箇所が明確だったり、その箇所の2つの修正どちらを選ぶか選択できたりと便利ですのでおススメですw）

修正したら再度、「add ⇒ commit ⇒ push」を行って問題なくプッシュできていたらOK！

## プル（pull）

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

```bash:
git pull origin develop
```

## スタッシュ（stash）

「あ、作業するブランチまちがえてた...。」
「このブランチで作業中だけど、別のブランチで作業ができたな。作業すごく中途半端だからコミットはしたくないな...。」
などというときに、**スタッシュ**を使います。
**スタッシュ**を使用すると、コミットしていない変更を一時的に退避することができます。
**スタッシュ**で変更を退避させて、別の作業をして、退避させていた変更を戻して作業を再開することなどができます。

```bash:
# 変更を一時退避
git stash

# コメントを付けて変更を一時退避
git stash save [コメント]

# 退避させた変更の一覧
git stash list

# 最新の退避させた変更を戻す（戻した内容は退避リストに残留）
git stash apply

# 退避リストから指定して退避させた変更を戻す（戻した内容は退避リストに残留）
git stash apply stash@{0}

# 最新の退避させた変更を戻す（退避リストから該当変更を削除）
git stash pop

# 退避リストから指定して退避させた変更を戻す（退避リストから該当変更を削除）
git stash pop stash@{0}

# 消したいstash名を指定して退避リストから削除する
git stash drop stash@{0}

# 退避リストを全削除する
git stash clear

```




## 追記✐
たまーに気分で更新。