Gitについて学んだことまとめ 


Githubを使ったことがあるし、なんとなく知っているけど、ちゃんとは理解できていないエンジニア未経験の私が
有識者の方々よりいただいたロードマップにそってGitについて学んだことをまとめたものです。

# 目次
1. Gitとは
2. Gitの操作方法
3. GitHubでのPRやMergeの仕方
4. Git Flow, Github Flowとは
5. 実際に使って便利だったGitコマンド

# 今回の学習のゴール
1. 代表的なコマンドがわかる（add, commit, push, rebase, merge, checkout）
2. GitHubでPRやMergeの仕方がわかる
3. Git Flow, GitHub Flowを知る

# 1. Gitとは
プログラムのソースコードなどの変更履歴を管理するシステム
いつ、誰が、ファイルのどの部分を変更したか記録でき、以前のファイルの状態に戻すことができる

# 2. Gitの操作方法
Gitの操作方法については、主に[Learn Git Branching](https://learngitbranching.js.org/?locale=ja)を使用し学習しました。

## 主なコマンド
![コマンド.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529506/bc2a679c-86ac-43de-2bf4-e4cd55fa4cc7.jpeg)


### add
指定したファイルの変更履歴をステージングエリアに追加し、変更履歴を残す準備する

```console
$ git add <ファイル名>
```

### commit
ローカルリポジトリへ変更履歴を記録する

```console
$ git commit -m "<メッセージ>"    # 何を変更したか等のメッセージをつけて、変更履歴を保存する
```

### diff
2つのテキストファイルを比較し、ファイル間の差分を出力する

```console
$ git diff <比較するファイル１> <比較するファイル２>
```

### push
ローカルリポジトリの変更履歴をリモートリポジトリへアップロードする

```console
$ git push origin <ブランチ名>    # どのブランチをプッシュするか指定する
```

### clone
コミットの差分を辿って全ての変更を取得できる

```console
$ git clone <URL>    # コピーしたいリポジトリのURLを指定
```

### branch
分岐の連なりの記録のこと
変更履歴を分岐して記録したり、合流させてそれぞれの変更内容を統合したりできる

```console
$ git branch <ブランチ名>    # ブランチを作成
$ git checkout <ブランチ名>    # 作業ブランチを変更
```

### merge
分岐したブランチを一つにまとめる
マージしたブランチのコミットが残る

```console
$ git merge <ブランチ名>
```
![merge.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529506/e3d69ae0-5ff5-28e9-37b1-c4fc7b93afaf.jpeg)

### Rebase
ブランチを一つにまとめる
リベースしたブランチが、一本の連続したコミットに整形できる

```console
$ git rebase <ブランチ名>
```
![rebase.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529506/abd040db-3069-ad39-8019-d610a940b6fc.jpeg)


## HEADにまつわるコマンド

HEADとは、チェックアウトされているコミットを指す時の呼び方で、今どのコミットで作業しているかを意味する

### ^（ハット）オペレータ

```console
$ git checkout master^    # masterの最初の親コミットへ移動できる
$ git checkout master^^    # masterのおじいちゃんコミットへ移動できる
```

### ~<num> オペレータ

```console
$ git checkout HEAD~4    # 4つ前のコミットへ移動できる
$ git branch -f master HEAD~3    # masterブランチをHEADから数えて3個前の親コミットへと強制（force）的に移動することができる
$ git branch -f master <コミット名>    # masterブランチを指定のコミットへと強制的に移動することができる
```

### git reset
ブランチのポインタを元に戻すことで変更のキャンセルができる
履歴を上書きし、前のコミットがなかったかのようにできる


```console
$ git reset HEAD~1    # ブランチのポインタを1前に戻す
```

### revert
変更を巻き戻して、その変更をリモート上で他の人と共有する際に使用

```console
$ git revert HEAD
```

### cherry-pick
HEAD（現在の位置）の下にコピーしたいコミットを持ってくることができる

```console
$ git cherry-pick <コミット名> <コミット名>...    # コピーするコミットは複数指定可能
```

### インタラクティブrebase -i
インターフェイス（vimなどのテキストエディタの中でファイルが開く）上で、どのコミットがrebase対象の下にコピーされるかを確認できる

```console
$ git rebase -i HEAD~
```

### tag
重要なコミットに印（タグ）をつけることができる

```console
$ git tag v1 <コミット名>    #v1というタグを指定するコミットにつける
```

### describe
複数あるコミットの中を移動する際に、現在いる位置を示してくれる

```console
$ git describe <参照>    # ブランチ, タグ, コミットハッシュ等を指定する
<タグ>_<コミット数>_g<ハッシュ>  # コマンドの結果
```

# 3. GitHubでPRやMergeの仕方
GitHub公式の[Issue とプルリクエストでのコラボレーション](https://help.github.com/ja/github/collaborating-with-issues-and-pull-requests)を参考にし学習しました。

### Pull Requestとは
 - 他者に対してあなたがGitHub上のリポジトリ内のブランチにpushした変更を知らせること
 - 同一リポジトリのブランチ間で、pull requestを作成でき、変更の承認を依頼することができる
     - リポジトリをフォーク※し、そのフォークに変更を加えた場合には、pull requestを作成することで上流リポジトリにその変更の承認を依頼することができる
 - Pull Requestでは、変更を加えたファイルとmergeするファイルの差分(diff)をレビューしたり、コメントしたりできる
 - Pull Requestで変更の承認がおりればmergeすることができる（リポジトリに対してpushできるユーザーであればmerge可能）

※フォークとは、ユーザが管理するリポジトリのコピーのこと
オリジナルのリポジトリに影響を与えることなくプロジェクトへの変更を行いたい時に使用

### merge conflict
- 競合するコミットを持つブランチをmergeしようとしたときに生じるものをmerge conflictという
- merge conflictは、GitHub上のconflict editorか、もしくは、コマンドラインとテキストエディタを使用して解決する

参照：[マージコンフリクトへの対処](https://help.github.com/ja/github/collaborating-with-issues-and-pull-requests/addressing-merge-conflicts)

# 4. Git Flow, GitHub Flowとは
Git Flow 及び GitHub Flow について自分なりに調べてまとめました。
どちらもGitにおけるリポジトリのモデルのことを指します。

### Git flow
Git flowでは、masterとdevelopの2つのブランチを軸に、それらを補助するfeature, release, hot-fixの3つのブランチを使い分けて開発を行う

masterブランチ：リリースしたデータを置いておくブランチ
developブランチ：開発を行うためのブランチ
featureブランチ：開発を行うためのブランチで、個々の機能の実装やバグの解決を行う
releaseブランチ：リリース前に微調整を行うブランチ
hot-fixブランチ：リリース後に、緊急の修正対応をするためのブランチ
![Git flow.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529506/e9e11dc6-97ca-956a-f6ca-64a83d41d081.jpeg)

このようにそれぞれのブランチに役割を持たせることで、ワーキングスペースが明確になり効率の良い開発を進めていくことができる


### GitHub Flow
git flowが簡略化されたもので、masterを軸に、説明的な名前（機能追加やバグ修正など）を付けたブランチを作成して開発を行う

1. ローカルの作業ブランチで作業が完了後、リモート上の同じブランチにpush
2. GitHub上でpull requestを出し、コードレビューをもらう
3. 必要があればローカルでコードを修正し、再度リモートへpush
4. コードレビュー及び修正が完了後、masterにmergeする

# 5. 実際に使って便利だったGitコマンド
- 特定のcommit位置でブランチを切りたい時（この時点からブランチ変えたかった、前のブランチでcommitし続けてしまっていた時など）

commit hashを確認

```
git log
```
特定のcommit位置でブランチを切る

```
git checkout -b <新しいブランチ名> <commit_hash>
```

## 参考
[Learn Git Branching](https://learngitbranching.js.org/?locale=ja)
[Issue とプルリクエストでのコラボレーション](https://help.github.com/ja/github/collaborating-with-issues-and-pull-requests)
[git flowとは一体どういうものなの？イメージしにくいgit flowを徹底解説！](https://blog.codecamp.jp/git_flow_whatis)
[git flowとgithub flowとは？その違いは？ - Qiita](https://qiita.com/mint__/items/bfc58589b5b1e0a1856a)
[Gitを最大限に活用できる「Git flow」で、効率よく開発を進めよう！](https://liginc.co.jp/248864)
[GitHub Flow 図解](https://qiita.com/tbpgr/items/4ff76ef35c4ff0ec8314)