blog

成功した Git ブランチモデル

この記事では、私が1年ほど前からすべてのプロジェクトで使っている開発モデルを紹介します。この開発モデルについてずっと書こうと思っていたのですが、今まで時間がありませんでした。この記事ではプロジェクトの...

Jul 14, 2025 · 11 min. read
シェア

この記事では、私が1年前にすべてのプロジェクトで使用し、大成功を収めた開発モデルを紹介します。この開発モデルについてずっと書こうと思っていたのですが、今まで時間がありませんでした。この記事では、ブランチ戦略とリリース管理だけで、プロジェクトの詳細には触れません。

なぜGitなのですか?

しかし、Gitではこのようなことはとても簡単で、ブランチとマージは日々のバージョン管理操作の中核の一つとさえ考えられています。例えば、CVS/Subversionの本では、ブランチやマージは後の章で扱われることが多いのですが、どのGitの本でも最初の3章で扱われています。

シンプルさと再現性の利点は、分岐やマージが怖くなくなることです。バージョン管理ツールは、ブランチやマージを簡単にするためのものです。

ツールを簡単に紹介した後、開発モデルを見てみましょう。私が説明したモデルは、基本的に、確実に管理されたソフトウェア開発プロセスを形成するために、各チームメンバーが従わなければならない一連のステップにすぎません。

分散型でありながら中央集権型

このブランチングモデルで使われているリポジトリ構成の中核は、うまく機能することが示されている、中央の「真実」リポジトリです。このリポジトリだけが中心とみなされることに注意しましょう。ほとんどの Git ユーザーはこの名前に慣れ親しんでいるので、このリポジトリを指すときには origin を使います。

各開発者はオリジンに対してプッシュとプルの操作を行います。しかし、この中央集権的なプッシュとプルの関係に加えて、各開発者は他の開発者やグループから変更をプルすることもできます。例えば、2人以上の開発者が一緒に大きな機能に取り組んでいて、作業中のコードをオリジンに対してプッシュしているような場合です。上の図では、AliceとBob、AliceとDavid、ClairとDavidというグループがあります。

技術的には、これはアリスがボブのリポジトリを指す bob という名前の Git リモートを定義しているだけです。

#p#

主な支店

この開発モデルの中核は、主に既存のモデルにインスパイアされています。中央のリポジトリには、無限の寿命を持つ2つのメインブランチがあります:

  • master
  • develop

Git を使う人なら誰でも、origin の master ブランチについてよく知っているはずです。master ブランチと並行して、develop というブランチがあります。

origin/developブランチのHEADソースには、開発中に行われた***コミットの変更が反映されていると考えてください。これを「統合ブランチ」と呼ぶ人もいるでしょう。このブランチは、日々のビルドを自動化するためのコードソースです。

develop ブランチのソースコードが安定した状態になったら、リリースを行うことができます。develop ブランチのすべての変更を何らかの方法で master ブランチにマージし、リリースバージョン番号をつける必要があります。この方法の詳細については、後で説明します。

つまり、master ブランチに変更がマージされるたびに、新しい製品のリリースが行われるということです。理論的には、master ブランチにコミットするたびに Git フックスクリプトを使って自動的にビルドし、製品環境サーバーにデプロイすることができます。

支援支部

開発モデルでは、master ブランチと develop ブランチの直後に複数のサポートブランチを作成し、チームメンバーの開発の並列化、製品機能の追跡、製品リリースの準備、製品問題の迅速な修正などを行います。master ブランチとは異なり、これらのブランチの寿命は限られており、最終的には削除されます。

使用するブランチは以下の通りです:

  • フィーチャーブランチ
  • リリースブランチ
  • Hotfixブランチ

これらのブランチにはそれぞれ特定の目的があり、どのブランチから発生し、どのブランチにマージして戻るかについて、厳密なルールがあります。これらについては、後で順番に説明します。

技術的な観点からは、これらのブランチはまったく「特別」ではありません。ブランチは、その使われ方によって分類されます。技術的には、これらはすべて通常の Git ブランチです。

#p#

フィーチャーブランチ

可能な分岐元:開発

developにマージする必要があります。

ブランチコマンドの規約: master、develop、release-*、hotfix-* 以外の名前。

機能ブランチは、次のリリースに向けて新しい機能を開発するために使われます。ある機能の開発が始まったとき、その機能がどのリリースに含まれるかはわからないことがよくあります。機能ブランチの重要な点は、その機能が開発されている間はずっとそのブランチが存在し続けるということです。しかし、最終的には develop ブランチにマージされるか破棄されることになります。

フィーチャーブランチは開発者のリポジトリにのみ存在し、オリジンには存在しない傾向があります。

機能ブランチの作成

新しい機能に取りかかる際には、develop ブランチから feature ブランチを作成します。

$ git checkout -b myfeature develop 
 
Switch to a new branch "マイフィーチャー” 

完成した機能をdevelopにマージ

完成した機能は、developブランチにマージして次のリリースに追加してください:

$ git checkout develop 
 
Switch to branch 'デベロップ' 
 
$ git merge –no-ff myfeature 
 
Updating ea1b82a..05e9557 
 
(Summary of changes) 
 
$ git branch -d myfeature 
 
Deleted branch myfeature (was 05e9557). 
 
$ git push origin develop 

上のコードで -no-ff フラグを指定すると、マージが早送りで行われた場合でも、常に新しいコミットオブジェクトを作成するようになります。これにより、機能のブランチの履歴に関する情報が失われることを回避し、コミットのグループが一緒になって機能を構成していることを明確にすることができます。次の図を比較してください:

2 番目のイメージでは、Git の履歴からどのコミットオブジェクトがその機能を構成しているのかを一目で見ることができなくなっています。この場合、機能全体をバックアップするのは少々面倒な作業となります。

確かに、そうすることでいくつかのコミット対象が生まれますが、そうすることの長所は短所を上回ります。

残念ながら、-no-diff をデフォルトの git マージの動作パラメータにする方法は見つかりませんでした。

#p#

出版部門

可能な分岐元:開発

developとmasterにマージする必要があります。

ブランチの命名規則: release-*

リリースブランチは、新しい製品バージョンのリリースの準備をサポートします。このブランチでは、すべての詳細を***時点でチェックすることができます。さらに、小さなバグを修正したり、バージョンリリースのためのメタデータを準備したりすることもできます。release ブランチでこれらの作業を行うと、develop ブランチの見た目がすっきりし、次のメジャーリリースの機能を受け入れやすくなります。

開発ブランチからリリースブランチを作成するタイミングは、通常、開発ブランチが新しいリリースの望ましい状態を反映したときです。少なくとも、そのリリースで計画されている機能が develop ブランチにマージされた時点です。他の将来のリリースに向けて計画されている機能はマージすべきではありません。

リリースブランチが作成された時点で、対応するリリースにバージョン番号が付与されます。その時点で、develop ブランチには「次のバージョン」に関連する変更が反映されますが、その「次のバージョン」が 0.3 なのか 1.0 なのかは、リリースブランチが作成されるまでわかりません。バージョン番号は、リリースブランチが作成されるときにプロジェクトのバージョン番号ルールに基づいて決定されます。

リリースブランチの作成

リリースブランチは develop ブランチから作成されます。たとえば、1.1.5 が現在の製品バージョンで、次のリリースが間近に迫っているとしましょう。develop ブランチのステータスはすでに「次のリリースの準備ができた」状態になっており、次のリリースは 1.2 になることが決定しています:

$ git checkout -b releases-1.2 develop 
 
Switched to a new branch 「リリース-1.2” 
 
$ ./bump-version.sh 1.2 
 
Files modified successfully. version bumped to 1.2. 
 
$ git commit -a -m “Bumped version number to 1.2” 
 
[release-1.2 74d9424] Bumped version number to 1.2 
 
1 files changed. 1 insertions(+). 1 deletions(-) 

新しいブランチを作成してそこに移動したら、バージョン番号を設定します。bump-version.sh は架空のシェルスクリプトで、新しいバージョン番号を反映させるためにローカルのワークスペースのファイルを変更します。次に、新しいバージョン番号をコミットします。

新しいリリースブランチは、そのバージョンが明示的に公開されるまでの一定期間、存在することがあります。この間、そのブランチではバグ修正が行われるかもしれません。そのブランチに新しい機能を追加することは固く禁じられています。新しい機能は develop ブランチにマージし、次のリリースを待たなければなりません。

リリースブランチの終了

リリースブランチがリリース可能な状態になったら、さまざまな作業を行う必要があります。まずリリースブランチを master にマージし、master ブランチのコミットにタグを付けて将来のリリースの履歴を探しやすくします。*** リリースブランチでの変更を develop ブランチにマージして、将来のリリースで関連するバグを修正できるようにします。

最初の2つのステップはGitで操作します:

$ git checkout master 
 
Switched to branch 'マスター' 
 
$ git merge –no-ff release-1.2 
 
Merge made by recursive. 
 
(Summary of changes) 
 
$ git tag -a 1.2 

リリースは完了し、今後のアクセスのためにラベルが貼られました。

注意:タグに-sまたは-u <key>をつけて署名することもできます。

また、変更をリリースブランチに残すには、そのブランチを develop ブランチにマージする必要があります:

$ git checkout develop 
 
Switched to branch 'デベロップ' 
 
$ git merge –no-ff release-1.2 
 
Merge made by recursive. 
 
(Summary of changes) 

この操作によってマージが衝突する可能性があります。見つかった場合は修正してコミットしてください。

これで本当に仕事が終わったので、****ステップではリリースブランチを削除します:

$ git branch -d release-1.2 
 
Deleted branch release-1.2 (was ff452fe). 

#p#

ホットフィックスブランチ

可能なブランチソース: master

developとmasterにマージする必要があります。

ブランチの命名規則: hotfix-*

Hotfix ブランチはリリースブランチとよく似ていますが、その目的は製品の新しいバージョンをリリースすることです。Hotfixブランチは、製品のバージョンに予期せぬ問題が見つかり、それを理解し対処する必要がある場合に使用します。製品バージョンの重大なバグを直ちに解決する必要がある場合、対応するバージョンタグからホットフィックスブランチが作成されます。

Hotfixブランチを使用する主な効果は、チームメンバーが作業を続けている間、別のメンバーがHotfixブランチで作業し、製品のバグ修正を素早く行うことができることです。

Hotfixブランチの作成

Hotfix ブランチは master ブランチから作成されます。たとえば、1.2が現在使用されている製品のバージョンで、重大なバグにより多くの問題が発生しているとします。同時に develop ブランチはまだ不安定で、新しいバージョンをリリースすることができません。ホットフィックスブランチを作成し、そのブランチで問題を修正することができます:

$ git checkout -b hotfix-1.2.1 master 
 
Switched to a new branch "hotfix-1.2.1  
 
$ ./bump-version.sh 1.2.1 
 
Files modified successfully, version bumped to 1.2.1. 
 
$ git commit -a -m “Bumped version number to 1.2.1″ 
 
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1 
 
1 files changed, 1 insertions(+), 1 deletions(-) 

Hotfixスコアを作成したら、新しいバージョン番号を設定することを忘れないでください!

その後、バグを修正し、1つ以上の別々のコミットを使ってコミットします。

$ git commit -m “Fixed severe production problem” 
 
[hotfix-1.2.1 abbe5d6] Fixed severe production problem 
 
5 files changed, 32 insertions(+), 17 deletions(-) 

Hotfixブランチの終了

修正が完了したら、hotfix ブランチを master にマージする必要がありますが、同時に develop にもマージして、関連する修正コードが次のリリースにも含まれるようにする必要があります。これは、リリースブランチを完成させるのとよく似ています。

まず、master ブランチを更新してタグを付けます。

$ git checkout master 
 
Switched to branch 'マスター' 
 
$ git merge –no-ff hotfix-1.2.1 
 
Merge made by recursive. 
 
(Summary of changes) 
 
$ git tag -a 1.2.1 

注意:タグに-sまたは-u <key>をつけて署名することもできます。

次に、修正コードをdevelopにマージします:

$ git checkout develop 
 
Switched to branch 'デベロップ' 
 
$ git merge –no-ff hotfix-1.2.1 
 
Merge made by recursive. 
 
(Summary of changes) 

この例外として、現時点でリリースブランチが存在する場合、Hotfixブランチの変更はdevelopではなくリリースブランチにマージすべきです。Hotfixをリリースブランチにマージするということは、リリースブランチが終了したときに、その変更が最終的にdevelopにマージされるということでもあります。

*** 一時的なHotfixブランチを削除します:

$ git branch -d hotfix-1.2.1 
 
Deleted branch hotfix-1.2.1 (was abbe5d6). 

短い

このブランチモデルには特に目新しいものはありませんが、冒頭の「パノラマ」は実際にプロジェクトでとても役に立ちました。それは、チームメンバーが共通のブランチとリリースのプロセスを素早く構築し、理解できるようにする、エレガントでわかりやすい概念モデルを作るのに役立ちました。

Read next

iOS クラスの性質を簡単に理解する

クラスはオブジェクトです クラスオブジェクトと呼ばれるオブジェクトのクラス型、任意の型、Objective-Cクラスを表し、クラス名はクラスオブジェクトを表し、各クラスは1つだけのクラスオブジェクトを持っています。

Jul 14, 2025 · 2 min read