Git002:Gitのブランチ運用法

#### おすすめのBranch管理　考え方
人やチームによって、Branchの管理は異なります。
あくまで私の経験上で良いと思ったBranch管理は下記の通りです。

①機能毎にBranchを作ってSoft変更する。
②MainのBranchでSoft変更を行わない。
　他の機能毎のBranchをMergeするだけとする。
　
キーポイントは機能毎にSourceを管理する事だと思います。
複数の機能の変更を合体して１つのブランチでCommitしてしまうと、どの変更がどの機能か分からなくなります。
各機能を実現するにはどの様な記述が必要かをブランチ毎にまとめる事が重要です。

そうなっていたら、Mainブランチは結合するだけのはずです。

#### Commitの注意点
Gitではたまに変更したSourceが消えてしまう、注意すべき挙動が有ります。

多くのGit HistoryのViewerはBranchの履歴情報だけを追って表示します。
つまり、「Branchに所属しないで変更したコミット内容は、別のBranchにCheck Outすると見えなくなる事が有る。」のです。

＜2種類のCheck out＞
```cmd:cmd
# 〇BranchのIDにCheck out
git checkout Grid

# △CommitのIDにCheck out(Branch未所属)　→注意が必要なのはこの時
git checkout 926267ef
```

例えば、VS Codeの拡張機能Git Graphで言うと、下記の2種類の場所で、右クリックからのCheck outができますが、挙動が違います。要注意です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884555/a7321848-8480-1e2a-ab52-bd417abfac2d.png)


〇BranchのIDとは分岐の最新のCommitがされた状態です。
　・BranchにCheck outして変更をCommitするとBranchが進んでくれます。
　→よって、基本的に安全です。

〇CommitのID 521aab005などにCheck outした状態でSoft変更すると
　・Branchに所属していない事になります。
　・この状態でSoft変更し、CommitするとCommitはどこにも所属していません。
　　VS codeのGit Graphなどでは見えなくなります、
　　Git的には消えてないけど、追いづらい存在になります。

なので、Soft変更時は下記のようにBranch上で作業を心がけるのが良いと考えます。
　・既存のBranchにCheck outし、Soft変更する。
　・CommitのIDにCheckoutしたら、新しいBranchを作ってCheckoutし、
　　Soft変更する。

  
#### おすすめのBranch管理　実際のやり方
①Soft変更は前回のVersionのBranchをCheck out 又はPullし、機能名のBranchを作ってCheckoutした状態からSourceを変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884555/4bfa5f61-74f8-8cec-e4c6-e2bcad80ce3f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884555/a248c648-13d2-b1bd-0f8c-1a4bb825705e.png)


②変更したFileは変更の欄にList upされます。
　変更が完了したら、＋ボタンを押してStagingします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884555/ddd483ed-22f6-9e83-ca16-c25717e8ad4f.png)

③変更内容の初回登録時はCommitのCommentに機能の仕様などを書いてCommitします。
単体動作確認などで修正したするたびにStaging→Commitの作業を繰り返します。機能Branchの中にどの様な機能でどのような修正をしたかを集約してまとめます。

④Release時にmainのBranchにCheck outし、Terminalで下記の様にMergeしていきます。
 
例)Version 0.00へのMerge
```
git checkout main
git merge --no-ff PlanGraph -m "Version 0.00a Merge PlanGraph"
git merge --no-ff master -m "Version 0.00b Merge master"
git merge --no-ff EnvironmentSetup -m "Version 0.00c Merge EnvironmentSetup"
```

※ff(fast-forward)とはMergeするBranchの変更履歴もMergeする動作です。
装置のBranchにはMerge情報とVersion情報だけにしたい為、--no-ffでMergeします。
VS codeでは--no-ffや細かい指定が難しいので諦めてCommandで実施するのをお勧めします。

※何らかの理由で異なる履歴を持つブランチ同士をMergeする場合は、--allow-unrelated-histories オプションを付ける事が有ります。
```
git merge --allow-unrelated-histories --no-ff EnvironmentSetup -m "Version 0.00a Merge EnvironmentSetup"
```

⑤MergeがうまくいかなくてMergeを中断したい場合は下記を実行。
```
git merge --abort
```

⑥Mergeすると下記の様になります。
　Git Graphはすぐに表示更新してくれない時が有るので、Checkoutし直し等をすると更新してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884555/ea462aed-30b9-2989-aa6e-4ca577ce072d.png)

・mainのBranchには細かい変更などは無いのですっきり見やすいと思います。

・Branchでは自由にFileを追加したり、削除しても大丈夫です。
　MainにMergeした時の履歴で最終的にどんな変更をしたかを比較で見られるからです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884555/08fc2f2b-95ce-de1b-e492-8a00237df669.png)

⑦Mergeの度に0.00a→0.00b→0.00c→・・・と上げていき、では最後のメジャーバージョンアップはどうするのという話になります。
Commitするには何かしらのFileを変更する必要が有るけど、Source Codeは機能Branchで管理してるし・・・。

ずばり、更新資料を更新します。
Version.txtかどんな名前かは分かりませんが、Version記述Fileを0.00から1.00のように書き換えたり、
変更内容の管理Fileだとか、有ると思います。

そのような更新資料と一緒にmainをCommitすると分かりやすいと思います。

1.00 = 0.00c+version file + α
0.00c =　0.00+PlanGraph+master+EnvironmentSetup
0.00b =　0.00+PlanGraph+master
0.00a =　0.00+PlanGraph