Skip to content

Commit

Permalink
Merge pull request #1299 from future-architect/feature
Browse files Browse the repository at this point in the history
Git flow
  • Loading branch information
ma91n authored Jun 11, 2024
2 parents c302861 + dd24b9e commit ffdde32
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions source/_posts/20240611a_Gitのブランチの役割を考える.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: "Gitのブランチの役割を考える"
date: 2024/06/11 00:00:00
postid: a
tag:
- Git
- ブランチ運用
category:
- Programming
thumbnail: /images/20240611a/thumbnail.png
author: 澁川喜規
lede: "Gitのブランチ戦略にはいくつかあります。チームの戦略を考えるときにどれかを参考にしつつカスタマイズするときにいろいろ不都合が生じてしてきて複雑になってしまうことってありますよね?社内でブランチの管理の議論をする中で、ブランチの役割を明確にした上で、どのブランチがどのような役割を持っているのかを明確にした方が混乱が少なくなるのではないか?というのを考えていました。"
---
Gitのブランチ戦略にはいくつかあります。

* Gitフロー
* GitHubフロー
* GitLabフロー

チームの戦略を考えるときにどれかを参考にしつつカスタマイズするときにいろいろ不都合が生じてしてきて複雑になってしまうことってありますよね?社内でブランチの管理の議論をする中で、ブランチの役割を明確にした上で、どのブランチがどのような役割を持っているのかを明確にした方が混乱が少なくなるのではないか?というのを考えていました。

特に、プロジェクトごとに同じ名前でも役割が違うなー、というのとかもあり、ブランチ名=役割ではなく、ブランチの上位概念として役割を考えて、それを実際のブランチとの対応づけを行う必要があるのではないかな、と。

CI/CDと組み合わされることで、releaseブランチ==ステージング環境となってしまい、ステージング環境を使いたいリリース前のブランチと、ホットフィックスの検証のブランチのブランチマージ戦略がごっちゃになったりして困っている、という相談を受けたこともあって、ぼんやりと考えていたことをまとめました。

このエントリーでは各フローの紹介の図は次のブログから引用しました。各フローの流れを同じスタイルで紹介していて見比べやすかったからです。なお、参照したエントリーではtrunk based developmentもありますが、本エントリーでは省略しています。

https://medium.com/@sreekanth.thummala/choosing-the-right-git-branching-strategy-a-comparative-analysis-f5e635443423


# ブランチの役割

4つの役割を考えてみました。この後説明しますが、このロールは直接ブランチ名と1:1でリンクするものではありません。

| 役割 | 何をやるところか? | 許可される変更作業 |
|:-|:-|:-|
| 作業 | ソースコードの変更(機能追加) | 直接のコミット、rebase |
| 集積 | いろいろな作業の結果を貯める | 作業ブランチや、他の集積ブランチのマージ |
| スナップショット | とある時点のコードを保存 | なし |
| 環境 | CDのトリガーとなって成果物を生成・デプロイ | なし |

環境ブランチというのは後述のGitLabフローから持ってきたもので、他のものは適当に考えてみた名前です。もし良い呼び名があれば提案をお待ちしています。


# 各フローのブランチと役割の対応

## Gitフロー

もしかしたら、この分類に違和感を感じるかもしれませんが、[オリジナルのGit Flow](https://nvie.com/posts/a-successful-git-branching-model/)になるべく忠実に書いています。あ、masterはmainに変えています。

| ブランチ | 役割 | 説明 | 分岐元 | マージ先 |
|:-|:-|:-|:-|:-|
| main | 環境 | リリース対象のコードを保持 | なし | なし |
| リリースタグ | スナップショット | リリースブランチをmainマージしたタイミングで打つ | develop | main |
| develop | 集積 | featureで作業した結果をマージ | なし | release/x |
| release/x | 作業/環境 | リリースに向けたバグ修正作業を行う | develop | main/develop |
| feature/x | 作業 | 機能の実装作業を行う | develop | develop |
| hotfix/x | 作業 | バグの修正作業を行う | main | main/develop/release(あれば) |

releaseブランチではバグ修正作業を行なって修正したものはdevelopに書き戻す、リリースが終わればブランチを削除ということがGitフローでは書かれています。つまり作業用ブランチなのですよね。今時はreleaseは直接コミット禁止にしてそこへの変更もPull Requestにするという運用が多い気がします。あとは、releaseブランチはstaging環境に対する環境ブランチになっており、ここにマージするとstaging環境も自動更新されるとかも良く見る気がします。

<img src="/images/20240611a/image.png" alt="image.png" width="720" height="462" loading="lazy">

## GitHubフロー

[GitHubフロー](https://docs.github.com/ja/get-started/using-github/github-flow)は明確なブランチ名を定義していません。ここではmainとfeature/xにしています。

| ブランチ | 役割 | 説明 | 分岐元 | マージ先 |
|:-|:-|:-|:-|:-|
| main | 集積 | featureで作業した結果をマージ | なし | なし |
| feature/x | 作業 | 機能の実装作業を行う | main | main |

ブランチを切ってコミットし、Pull Requestを作成してそれ上でコメントをしたりレビューします。完了したらGitHubの機能を使ってマージします。

GitHub Actionsを駆使するのも最近ではよく行われていますね。mainではデイリーでビルドを走らせてnightly buildを作成する、というのが行われることもあります。その場合は環境ブランチでもある、ということになります。main上でタグを打ったらリリース、という場合は、このタグがスナップショットですね。

GitHubフローだけだとCD環境へのデプロイとかのルールはこの上には作りづらいため、GitHubフローはプリミティブなビルディングブロックとしてGitフローやGitLabフローをアレンジした戦略を組み合わせて使うことが多いでしょう。

それにしても、GitHubフローのドキュメント、プルリクウェストってカタカナ表記が渋いですね。Pull Requestを発明したGitHub公式が書いているので、全日本語話者が使うべき正しい日本語表記はプルリクウェストということになりますね!プルリクエストとかいたら間違いです!

<img src="/images/20240611a/image_2.png" alt="image.png" width="720" height="357" loading="lazy">

## GitLabフロー

GitHubフローに各種環境用のブランチを足したものがGitLabフローです。GitHubフローに従う、というfeatureブランチもとりあえずここで入れています。GitLabはSaaSでありつつも、OSSとしてバージョンを打ってリリースもしているため、その2つのリリース物件に対応するブランチ戦略になっています。

| ブランチ | 役割 | 説明 | 分岐元 | マージ先 |
|:-|:-|:-|:-|:-|
| main | 集積 | featureで作業した結果をマージ | なし | なし |
| feature/x | 作業 | 機能の実装作業を行う | main | main |
| stable/x | スナップショット | バージョンごとのブランチ | main | なし |
| staging | 環境 | ここにマージするとstaging環境にデプロイ | main | pre-prod |
| pre-prod | 環境 | ここにマージするとpre-prod環境にデプロイ | staging | production |
| production | 環境 | ここにマージするとproduction環境にデプロイ | production | なし |

<img src="/images/20240611a/image_3.png" alt="image.png" width="720" height="410" loading="lazy">

# まとめ

Gitのブランチ戦略を考えるのは、なかなか頭を使う作業です。実際にどのようなコミットが行われるのか、デプロイ先は1つなのか?(SaaSとかの場合)、複数同時にリリース物件を管理する必要があるのか(RubyとかPythonみたいに複数のマイナーバージョンが同時にサポート対象にして管理しなければならない場合)とかの条件によっても変わってきます。今回の記事では戦略を考えるためのメタな「ブランチの役割」について考えてみあした。

また、今時のGitは基本分散リポジトリとして使うのではなくて、GitHubやGitLab上の中央集権で使うということで、それらのサービスの提供するブランチ保護機能も考慮した作戦立案が必要不可欠でしょう。あ、もちろん、GitHubやGitLabを使ってない人はそれらを考えずに自由に作戦を考えても良いと思います。僕の周りではこの2つ以外はもう最近は見かけないのでこれらを前提で考えています。

前回書いた[2024年Gitワークフロー再考](https://future-architect.github.io/articles/20240410a/)は、作業ブランチと集積ブランチだけに特化した、GitFlowの範囲内の話でした。ブランチの役割が変わればもちろん、いろいろ変わってきます。集積ブランチであれば直接コミット禁止にして、そこの中ではrebase禁止にしないと、フォークしたブランチのマージができない、ということになります。


Binary file added source/images/20240611a/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added source/images/20240611a/image_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added source/images/20240611a/image_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added source/images/20240611a/thumbnail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ffdde32

Please sign in to comment.