Gitのバックマージが怖かったので練習してみた

# はじめに
最近、PR（プルリクエスト）を適切な粒度に分割することを考えるようになりました。

ただ、その場合バックマージをすることが多くなると思い、バックマージの不安点を練習してみた。

# 想定ブランチ構成
・develop 
・feature/test1-A
・feature/test1-B

# シチュエーション
test1という機能を追加したい。
とはいえ、test1という機能は大きく、A機能とB機能があり1つのPRだと大量の変更になってしまう。

しかも、厄介なことにA機能とB機能で改修するクラスがかぶっている。

レビューがしやすい様に、A機能とB機能のPRを分割。
とはいえ、レビューを直列にすると２倍の期間になってしまう。

ので、A機能とB機能のPRを並行して依頼を出す。

# やりたきことの流れ
１．developブランチから、feature/test1-A を作成し、PR（test1-A → develop）を出す。
２．更に並行して、feature/test1-A から feature/test1-Bを作成し、PR（test1-B → test1-A）を出す。
３．test1-AのPRレビューが完了後、developへマージ。
４．test1-BのPRレビューが完了後、マージ先を developに変更してマージ。

# 不安な点
test1-AのPRレビュー時に修正が発生した場合は、test1-Bにバックマージを行う必要があるが、バックマージに不慣れなのでドキドキ。

# バックマージのやり方
## その１
```
git switch feature/test1-B
git pull origin feature/test1-A
```
## その２
```
git switch feature/test1-B
git fetch
git merge feature/test1-A
```
## その３
```
git switch feature/test1-B
git fetch
git merge origin/feature/test1-A
```

## 気になっていること
その１とその２は同じ？

https://www.atlassian.com/ja/git/tutorials/syncing/git-pull

を見ると、pullは fetchしてmergeしているようなので同じはず？

その２とその３は同じ？

ローカルブランチからか、リモートブランチからかの違いのはずだから、最新化していれば同じはず？

# やってみる。
## 事前準備
```
git switch develop

git branch feature/test1-A
git switch feature/test1-A
echo 'A機能の追加' >> test1.txt
git add .
git commit -m 'A機能の追加'
git push origin feature/test1-A

# PR作成
gh pr create
# PR確認
gh pr view --web

git branch feature/test1-B
git switch feature/test1-B
echo 'B機能の追加' >> test1.txt
git add .
git commit -m 'B機能の追加'
git push origin feature/test1-B

# PR作成
gh pr create
# PR確認
gh pr view --web

```

## test1-Aで修正発生
```
git switch feature/test1-A
vi test1.txt
A機能の追加 → A機能の追加の修正
git add .
git commit -m 'A機能の追加の修正'
git push origin feature/test1-A

```

## test1-Bにバックマージ
### git merge feature/test1-A
```
git switch feature/test1-B
git fetch
git merge feature/test1-A
コンフリクトが発生
vi test1.txt
git add .
git commit
git push origin feature/test1-B
```
#### PR上の見え方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206526/909d5dfa-7ee9-4379-a54e-303c7fcd0873.png)

#### コミットコメント
```
Merge branch 'feature/test1-A' into feature/test1-B
```


### git merge origin/feature/test1-A
※ 一からやり直すのは手間なので、test1-Aで修正発生の手順で、さらに「修正」を付け加えていく。
```
git switch feature/test1-B
git fetch
git merge origin/feature/test1-A
コンフリクトが発生
vi test1.txt
git add .
git commit
git push origin feature/test1-B
```

#### PR上の見え方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206526/f6491594-5d31-476c-a4bd-c7de427b3fa4.png)

#### コミットコメント
```
Merge remote-tracking branch 'origin/feature/test1-A' into feature/test1-B
```

### git pull origin feature/test1-A
※ 一からやり直すのは手間なので、test1-Aで修正発生の手順で、さらに「修正」を付け加えていく。
※ fetchしなくてもよいはずだが、なんとなくしてしまった。
```
git switch feature/test1-B
git fetch
git pull origin feature/test1-A
git push origin feature/test1-B
```

#### PR上の見え方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206526/a369d8c0-3b99-44d1-9a33-f6ab5dbf112f.png)

#### コミットコメント
```
 Merge branch 'feature/test1-A' of https://github.com/tarosuke777/sandbox into feature/test1-B
```


# やり直しコマンド
```
git switch develop
git branch -D feature/test1-A
git branch -D feature/test1-B
git push origin --delete feature/test1-A
git push origin --delete feature/test1-B
```

# 個人的結論
どれも、ローカルを最新化していれば一緒の雰囲気。

コミットコメントのマージ元が変わるので、レビュー時にどこからマージしたのかよくわかる。

git pull は楽だけど、せっかくコマンドが分かれているので、git fetch + git merge を使っていこうかな？と思った今日のこの頃。

だいぶマージに慣れてきた気がする。ので、バックマージが苦手な方は、個人で練習してみるのはおすすめです。

# おまけ
最終的な樹形図はどうなっているか、気になったので見てみました。
意図通りかなって感じでした。

```
$ git log --graph --oneline
*   3ef6ba0 (HEAD -> develop, origin/develop) Merge pull request #8 from tarosuke777/feature/test1-B
|\
| *   714c110 (origin/feature/test1-B, feature/test1-B) Merge branch 'feature/test1-A' of https://github.com/tarosuke777/sandbox into feature/test1-B
| |\
| * \   cf65eda Merge remote-tracking branch 'origin/feature/test1-A' into feature/test1-B
| |\ \
| * \ \   ccbe8c2 Merge branch 'feature/test1-A' into feature/test1-B
| |\ \ \
| * | | | 79a8b7e B機能の追加
* | | | |   2052a21 Merge pull request #7 from tarosuke777/feature/test1-A
|\ \ \ \ \
| | |_|_|/
| |/| | |
| * | | | df1ebf6 (origin/feature/test1-A, feature/test1-A) A機能の追加の修正の修正の修正
| | |_|/
| |/| |
| * | | 3ee5d88 A機能の追加の修正の修正
| | |/
| |/|
| * | 2ce5449 A機能の追加の修正
| |/
| * 2be5105 A機能の追加
|/
* 253dbc0 Initial commit

```

# おまけその２
https://github.com/tarosuke777/sandbox/pull/7

https://github.com/tarosuke777/sandbox/pull/8