現場で必要な最小限のGit

## はじめに

新人が入場する度に説明をしていたGitですが、現場で使っているコマンドって限られているし、必要な範囲のみ理解しておけば作業はできるのでは？と思いました。
後は使いながらGitに慣れること、トラブルの場合は調べながら解決する方法で十分だと思います。

まず、
##Git用語

|用語|説明|
|:---|:---|
|repository|ソース履歴管理を行う保管場所。ローカル(local)、リモード(remote)の２つがある。|
|work tree(workspace)| 履歴管理を行いたいファイルがある場所。物理的に自分のPC上、ソースが存在する場所。|
| index(stage)| ワークツリーからコミットしたいファイル又はファイルの一部を登録すること。|
| head| 作業対象となっているブランチの作業コミットポインター。|
|pull request（PR） <br>or<br>Merge request（MR）| 作業ブランチを作成し、マージしたいリポジトリのブランチを依頼すること。ブランチとブランチで紐付いてるので一回依頼するとクローズしない限り有効になる。<br>（依頼した後に作業ブランチあるいは依頼元のブランチが変更、更新されても再依頼の必要はない）|
| branch| ブランチ 作業をするGit上の場所、一般的に作業単位になる。ブランチを使うこちにより、複数の履歴を並列に管理できる。|
|conflict|マージ対象の２ファイルで同じ箇所が変更されており、自動でマージができないこと。|
|stage（unstage）|コミット対象にする状態。（変更はあったもののコミット対象外）|

## Git作業者名の登録

ソースをコミットする際に履歴を残す必要があるため、自分のGit情報を登録します。レポジトリ事にも設定可能だが、一般的にはグローバル設定をします。ソース履歴でコミッターに表示されるので分かるように登録しておきましょう。

```
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
```

登録情報を確認するには、

```
$ git config -l
```

## 作業の前に

Gitのデフォルト設定は大文字、小文字が検知しない設定になっているため、これからGit情に作成ものについて小文字することをお勧めします。
また、Gitのコマンドを打つと何かしらGitからメッセージが表示されますが、これだけよく読んでみるとほぼ状況が分かるし、トラブルでも解決できます。（英語ですが難しくないのでよく確認しましょう。）

## Git管理をスタート

すでに存在するソースをリモードからダウンロードしたいときは、

```
$ git clone https://github.com/xxxx/xxxx.git
```

ローカルからソース管理を始めるときには
（すでにGit管理されているところでこれをすると初期化されます。）

```
$ git init
```

ローカルのソースをリモードにアップロードするために設定、既存のgitからリモードを変更したい場合も可能です。
(`git clone`でソースを取得した場合はいらないです。)

```
$ git remote add origin http://xxxxxx.xxx/xxxx
```

## ソース取得ができたら

上記の作業が問題なければ作業ソースと以下のhiddenファイルが存在（生成）してあると思います。
`.gitignore`はなければ作成する必要あります。

`.git　`
履歴情報を持っているGitファイル（これを過去のものに上書きしたりしてPushすると悲惨な事故になる。）

`.gitignore`
ソース管理対象がにする定義ファイル（これをしていしないと管理不要なファイルも履歴管理対象になるため、gitが重くなります。）

## Gitコマンドのイメージは

![D3353CE0-52F3-4E45-AE61-36A2E264E79B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32323/eed006a1-a26b-b503-da06-2057d08d3e25.png)


### 作業中に使いそうなGitコマンド

#### git checkout　

ヘッドを切り替えること。　過去のコミットを対象にチェックアウトした場合、それをもとにコミットすることはできません。

```
$ git checkout feature/add_xxxx
```

#### git add　
対象ソースをstageします。（コミット対象にする）

```
# 全てのファイルをstageする
$ git add .
```

#### git reset

コミット前の変更をローカルリポジトリの状態へ戻すこと。また、特定のコミットまで状態を戻すこと。ただし、ローカルリポジトリに限られる。

```
# 全てのファイルをunstageします。（コミット対象外にする）
$ git reset

# 直前のコミットを削除し、内容をstage状態にします。
$ git reset HEAD^

# --hard オプションをつけると完全に捨てます。（stageに残さない）
$ git reset --hard
$ git reset HEAD^ --hard
```

#### git commit　

stageされたソースをローカルリポジトリに反映すること。

```
$ git commit -m "first commit."
```

#### git stash

コミットはしなくないけど臨時的に作業ソースを退避させる、退避させてソースを戻す時に使います。

```
# stashする
$ git stash

# stashしたリスト確認
$ git stash list

# stashから戻す(変更の復活と、削除を同時に行う。)
$ git stash pop stash@{0}
```

#### git log

ローカルリポジトリの履歴が確認できます。

```
# 読みづらい場合一行でみる
$ git log --oneline
```

#### git status

ローカルリポジトリ作業状況の確認します。（state, unstageされたソースの確認ができます。）

#### git branch

作成されているブランチを表示します。（現在作業ブランチも分かります。）

### 作業内容をリモートに反映するときにgitコマンド

![A7491C7E-6D70-4AA6-B56A-09B769C4AA85.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32323/62020f36-d99e-ecea-91af-54ed6b9ec0c6.png)

![884FC5D9-A9CC-47EC-B12E-A5277ACF204E.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32323/cbe95b1c-e08f-50c4-f11a-a4556fb30c9c.png)


#### git push

ローカルリポジトリの変更をリモートリポジトリに反映させます。

```
$ git push origin feature/add_xxxx
```

#### git pull

リモートリポジトリの変更をローカルリポジトリに反映させます。（フェッチしてマージします。）

```
$ git push origin master
```

#### git fetch

リモートリポジトリの変更のローカルリポジトリ追跡に反映させます。（マージはされません）

- 自分の作業コミットがそのまま先頭に移動するので履歴が分かりやすくなる
- マージではないため、作業コミットを作らない。
- リベース対象のコミットが多い場合、作業が面倒（コミット単位でcomplict作業をするため）

```
$ git fetch
```

#### pull request（PR） or Merge、request（MR）

Web上から行う作業なので見れば分かる現場の運用ルールがあるはずです。（GitHubあるいはGitLab）

### リモートに反映する時にコンプリクトしたら

#### git rebase

異なるブランチの変更を反映させます。（コミットがブランチ単位に並べられます。）

```
# 1. 作業ブランチにチェックアウトした状態で、masterにリベースを行う。
$ git rebase master

# 2. リベース途中でコンプリクトが発生した時に解消した後、続けたる時
$ git rebase --continue

# 3. conplictした場合、テキストエディターで修正を行う。そしてgitへ反映
$ git add .

# 2.~3.を繰り返してリーベスを進みます。

# リベース途中でやめる場合は（リベース作業前に戻る）
$ git rebase --abort
```

#### git merge

異なるブランチの変更を反映させます。（コミットが時系列になるため、お互いのマージコミットが残ります。）

- 一回の作業でブランチが最新化になる。（対象のコミットが多い場合、有利）
- 作業コミットができる（マージするため）
- マージするため、コミットが時系列になってしまう。（自分のコミットと他のコミットの順が時系列になる）

```
# 作業ブランチにチェックアウトした状態で、マージをする。
$ git merge master
```