開発でよく使うgitコマンドをユースケースごとに並べます

## 概要
過去にインターン生にgitを教えるとき、普段は猿でも分かるhogehogeを読んでくれと言っていたのですが、ユースケースでよくあるケースを用意しておかないとネットで見た内容を鵜呑みにして何も考えずにgit mergeしたりgit rebaseしたり迷走することがありました。

今回は開発していたら遭遇するであろうケースをいくつか並べて、「よくあるユースケースの一連の流れ」を雑多に並べてみました。

## gitあるあるユースケース:

### 最初の儀式

```
git clone hogehoge

ユーザー名とメアドの設定が必要なら下記
git config --global user.name <ユーザー名>
git config --global user.email <メールアドレス>
```

### 基本的な反映内容の更新

```
git checkout develop(devブランチに該当するもの)
git pull
```

### 一般的な開発スタイルの流れ

```
# ブランチを作る
git checkout -b <開発するブランチ名>
# 反映
git add .
# コミット
git commit -m 'hogehoge'
# プルリク
git push origin <開発するブランチ名>
```

### 他のブランチで作業中にリモートブランチのmasterが更新されて、取り込む必要が出てきた時

```
# origin を更新
git fetch origin
# 作業中ブランチへ master を取り込む
git merge --no-ff origin/master
あるいは
git rebase master
```

--no-ffを入れると、明示的に「作業中にブランチにmasterをちゃんとマージしたよ」というマージコミットが反映されるようになります。しかし、これを入れるべきかはチームの運用方法に依存するので要相談です。

個人的には残した方が良いと考えています。理由は、**何かの理由でmergeを取り消さないといけなくなった場合に非常に面倒臭い事態が発生してしまうためです**。--no-ffをつけておくことによってマージコミットが参照できるので、もしmergeを取り消さないといけない事象が発生した場合は**mergeコミットを取り消すだけでmerge作業自体を無かったことにできるので対処が簡単**です。気になる方は、fast-forwardとno-fast-forwardの違いについて調べてみると良いかと思います。

また、もう一つの方法としてrebaseがあります。こちらでも大丈夫で、コミットログが綺麗になるメリットがあるのでとてもスッキリします。ただし、コンフリクトが発生した時に複数回対応しなければならないので、コンフリクトが発生しやすい開発をする場合だと一回でコンフリクトが解消するmergeに軍配が上がるかもしれません。

### 相手が開発したブランチを取り込んで検証や確認などを行う場合

```
→リモートブランチをチェックアウトする
# リモートに対象のブランチの存在確認(補足程度)
git branch -r
# 欲しいブランチのリモート追跡ブランチをfetchする
git fetch origin <検証したいブランチ名>
# チェックアウトする
git checkout <'検証したいブランチ名'>
```

### 検証で動かしていたソースコードをローカル限定で回避させたい場合

.gitignoreだと全体で回避されてしまうのでローカル限定でコミットに不必要なファイルを退避させる方法ですが、`.git/info/exclude`に反映したくないファイル名を記載すればローカルで無視したいファイルを退避させることができます。

## 他の開発者の意見
SARAHのエンジニアから頂いた意見だと、こんなものがありました。

### checkout vs switch

こちらはバックエンドの田中さんが指摘してくれました。

https://qiita.com/sho-jp

ほとんどの入門書には`git checkout ブランチ名`という形でcheckoutが使われていますが、switchによる方法も存在します。

実際、switchのaliasを設定してcheckoutのaliasを捨てろという記事があるくらいです(厳しい...)

https://blog.toshimaru.net/git-switch-restore/

この理由にもちゃんと背景があって、例えばブランチAとブランチBでコンフリクトが発生したケースがあるとします。この時、一方のブランチの変更を全面的に支持する場合、下記のコマンドで簡単にコンフリクトを解消させることができます(詳しくは下記の記事を参照)。

```
checkout --ours hogehoge
checkout --theirs fugafuga
```


https://qiita.com/nantekkotai/items/2ed17c3d774211d234a4


これらの機能と混在するためにswitchを使用した方が良い背景があるみたいですが、実際僕も周りの方もcheckout派でした。こちらを指摘してくださった田中さんは、switch派の方とどちらの方が使ってる方多いのかなと気になっていました笑

### rebaseも入れた方が良い

こちらはiOSエンジニアの行木さんが指摘してくれました。

https://qiita.com/ukit-tokyo

こちらもagreeだったので反映しました。

追記(2022/8/25)
行木さん曰く、開発形態によってmergeを使うかrebaseにするかチーム内で統一した方が良いと仰ってました。どちらが良いのかを事例で例えると、例えば取り敢えずWIPでプルリクを投げる場合は、レビューを随時もらいながら機能を実装するのでmergeの方が良いと言っていました。また、ウォーターフォール型で開発が一直線の場合はテストなどを全て通してからプルリクを投げるので、rebaseだと綺麗なコミットログになるのでオススメと仰ってました。取り敢えずプルリクを投げた後にレビューをもらいながら開発するスタイルでrebaseを使用してしまうと、コミットidが書き変わってしまうので、レビューがトップに来てしまうなどの弊害があるらしいので、そういう開発スタイルの場合はmergeが推奨されるみたいです(行木さん細かいアドバイスありがとうございました！)。

## まとめ
今回はgithubの開発でよく使うコマンドをユースケースごとに並べてみました。コマンドの細かい説明を入れると長文になってしまうので、分からないコマンドがあったら猿でも分かるgithub入門などをみて理解してみると良いと思います。また、今回はgithub上でのプルリクの方法、コンフリクトの対応方法などは記載してませんのでご容赦ください。

基本的に開発していたらこれ以外の事例に遭遇することは稀なので、これだけ出来ていれば最低限の開発には対応できると思います。これを備忘録として用意するだけでも、新卒や未経験のインターン指導でも少し活かせるかなと思って書いてみました。

## 告知
SARAHでは「おいしい」一皿をユーザーに届けるためのサービス開発に取り組んでいます。インターンや正社員を問わず募集しておりますので、興味のある方はぜひカジュアル面談に来ていただけると嬉しいです。

書いた記事や開発した機能についても周りの方が気さくに意見をくれるので、とても良い環境だと思います。

## 参考文献
なるべく参考になりそうなものをピックアップしてみました。よかったら参考になると嬉しいです。

https://qiita.com/muran001/items/dea2bbbaea1260098051

https://sinsoku.hatenadiary.org/entry/20111025/1319497900

https://qiita.com/tommy_aka_jps/items/211c3f6ef961a066a4b7

https://blog.toshimaru.net/git-switch-restore/

https://snowsystem.net/git/git-command/git-switch/