トピックブランチを切る運用と切らない運用


本記事は、「パッケージソフトウェア開発 Advent Calendar」6日目の記事です。

以前、Git を用いてチーム開発をするにあたって、トピックブランチを切ることの理由を問われたことがありました。
そのとき、うまく答えられなかったので整理してみます。

なお、GitHub などの Pull request を使用していない Git を利用した開発の話を想定した内容です。

# 1人でトピックブランチを切る運用をした場合

1人でトピックブランチを切る運用をした場合の内容をコミットツリーの図で表現してみます。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/10443/8b816442-2f79-3e8d-2d53-44ed6bb7c4b7.png)

まず修正を開始するためにブランチを作成し HEAD をそれに切り替えるため、```git checkout -b <トピックブランチ名>```を実行します。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/10443/7497a8b0-0048-6419-778f-f297fa1e8cf2.png)

次にトピックブランチでローカルで実施した修正を```git commit```などでコミットします。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/10443/8ca58713-1c09-ce54-4f9c-b4a4f8e76ccd.png)

トピックブランチの内容をmasterに反映するため、一旦 HEAD を master に移動させます。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/10443/d4a51484-21eb-40ad-b7f6-e1ddd1383c13.png)

```git merge --no-ff <トピックブランチ名>```でトピックブランチを master にマージします。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/10443/9c362179-5881-aaad-c395-f6379c42fa88.png)

不要になったトピックブランチを```git delete -d <トピックブランチ名>```で削除します。

![6.png](https://qiita-image-store.s3.amazonaws.com/0/10443/4660d46e-7dd0-bceb-f255-28ac7b06dc6a.png)

正直面倒な感じです。
ただ、コミットツリーが枝分かれしていることで、master ブランチに修正を取り込んだということが伝わりやすい利点もあります。

# 1人でトピックブランチを切らない運用をした場合

次に1人でトピックブランチを切らない運用をした場合の内容をコミットツリーの図で表現してみます。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/10443/8b816442-2f79-3e8d-2d53-44ed6bb7c4b7.png)

ローカルで実施した修正を```git commit```などでコミットします。

![7.png](https://qiita-image-store.s3.amazonaws.com/0/10443/323483fa-f51a-3467-a416-acdf304a2e12.png)

とても簡単に終わります。
コミットツリーが一直線になっていきます。

# 複数人でトピックブランチを切る運用をした場合

今度はチームで開発する場合の場合について述べていきます。

では、複数人でトピックブランチを切る運用をした場合の内容をコミットツリーの図で表現してみます。

![8.png](https://qiita-image-store.s3.amazonaws.com/0/10443/51d7a81f-6cb1-7552-2c1b-bd21ad0c4c53.png)

まず、Aさんが「1人でトピックブランチを切る運用をした場合」でやったようにトピックブランチを切って master にマージします。

![9.png](https://qiita-image-store.s3.amazonaws.com/0/10443/1afeeec2-dd02-c418-1c4e-7673fc4a0a5d.png)

そして、A さんが ```git push origin master``` でリモートに反映します。

![10.png](https://qiita-image-store.s3.amazonaws.com/0/10443/45892c76-70ed-457f-db8f-4f86f524654f.png)

さて、B さんが別の修正を実施していて、トピックブランチにコミットしました。

![11.png](https://qiita-image-store.s3.amazonaws.com/0/10443/ee94e5c5-337c-80fb-9ad6-b0d0c158a520.png)

B さんは master にマージする前に master ブランチが他の誰かの修正を取り込んでいるかもしれないので、```git pull origin master``` で master を最新にします。

この際の pull では master に対して何も修正していないため、Fast-forward マージとなります。

![12.png](https://qiita-image-store.s3.amazonaws.com/0/10443/402aa76b-90f7-10dd-f3ec-38b402c46ef7.png)

B さんは、最新にした master をチェックアウト後、master にトピックブランチをマージします。
この際、master との内容によってはコンフリクトがこのタイミングで発生します。

![13.png](https://qiita-image-store.s3.amazonaws.com/0/10443/70eda83d-3743-bbff-7c59-f631f8a5f58a.png)

最後に B さんが ```git push origin master``` でリモートに反映します。

![14.png](https://qiita-image-store.s3.amazonaws.com/0/10443/01ae1337-7b9a-79d4-932b-ae2bd2e1c1e5.png)

この方法とった場合の利点はリモートにあるブランチである master に対しては、push する直前以外には修正をしないことです。
これにより、B さんが master を pull するタイミングでは Fast-forward マージになるのが保証されているので、そのタイミングでコンフリクトが起こることがありません。

また、このコミットツリーの構成は Pull request 運用した場合と同様の形になります。

# 複数人でトピックブランチを切らない運用をした場合

最後に複数人でトピックブランチを切らない運用をした場合の内容をコミットツリーの図で表現してみます。

![8.png](https://qiita-image-store.s3.amazonaws.com/0/10443/32e055b1-1a1d-9102-82e7-f9887636d01d.png)

A さんがローカルでコミットをします。

![15.png](https://qiita-image-store.s3.amazonaws.com/0/10443/3814074a-9507-6371-a908-e651f3e6c093.png)

A さんは ```git push origin master``` でリモートに反映します。

![16.png](https://qiita-image-store.s3.amazonaws.com/0/10443/f688ec50-08a5-24bd-6e0d-f4d711863a2c.png)

B さんが別の修正を実施していて、ローカルでコミットしました。

![17.png](https://qiita-image-store.s3.amazonaws.com/0/10443/09228404-fff8-b97f-ea50-0ae510559667.png)

B さんは master にマージする前に master ブランチが他の誰かの修正を取り込んでいるかもしれないので、```git pull origin master``` で master を最新にします。

そうした場合、Fast-forward マージはできません。
そのため、場合によってはコンフリクトがこのタイミングで起きます。

![18.png](https://qiita-image-store.s3.amazonaws.com/0/10443/d96c148d-0342-ce01-77b6-69f27135621d.png)

B さんは```git push origin master``` でリモートに反映します。

![19.png](https://qiita-image-store.s3.amazonaws.com/0/10443/408761d0-2512-d7ec-bed8-a3aad7d35ccc.png)

個々の作業自体は簡単です。
ですが、1人でやった場合と異なって、コミットツリーが一直線にはならなくなります。

また、pull のタイミングでコンフリクトが発生する可能性があるので、個人的にはあまり直観的ではない気がしています。

# まとめ

コミットツリーの図を用いて、トピックブランチを切った場合と切らなかった場合、どのようになるかを述べました。

ちなみに自分の場合、個人ではトピックブランチを切らない形で、社内などのチームでやる場合はトピックブランチを切る形で運用しています。
実際にどう運用するかは上記 4 パターンの挙動を理解した上で、好みで決めればよいと思っています。