現在、世界でも多くの開発者がシステム開発、アプリ開発の際に使用しているバージョン管理システム「Git」ですが、開発体制が大きくなるに従い、
「ソースコードのコンフリクトが頻繁に起きてしまう」
「先祖返りばかり発生して、なかなかプロジェクトが思うように進まない」
「Gitは導入するだけじゃダメなの?」
なんてことは無いでしょうか?
本記事では、バージョン管理システムの必要性と重要性、さらにGitを使用したバージョン管理のワークフローのうち、最もメジャーな「Git-flow」の運用とケーススタディについて、ご紹介致します。
バージョン管理の必要性と重要性について
本記事では主にバージョン管理システム「Git」を使用したワークフローについての解説をいたしますが、Gitについての解説に入る前に、開発をするうえで欠かせないバージョン管理の必要性と重要性について少し触れておきます。
「バージョン管理」とは一体何でしょうか。これは開発の中で更新されていくソースコードやファイルの変更を記録することです。
さらにそのサポートしてくれるソフトウェアのことをバージョン管理システムといいます。
では、なぜそのバージョン管理システムが開発をする上で必要になってくるのでしょうか?
バージョン管理システムを使用することによって、以下のことが可能になります。
- 変更履歴の記録(= commit)
- 変更の取り消し、復元
- 変更理由、その担当者の履歴
バージョン管理システムを使用せずに開発を進めてしまうと、他の作業者が編集した内容に気づかずに、ソースコードを上書きしてしまったり、時には不要なコードと認識し、削除してしまい、結果としてエラーや*デグレートが多発してしまうことになります。
(*デグレートとは、ファイルを更新した際に以前修正したバグや不具合が再発してしまうことです。)
しかし、上記の3つが可能になった場合はどうでしょう?
変更履歴を辿ることで、変更理由が確認でき、さらにその担当者も確認できるので、不用意にコードを削除してしまうことも無くなるでしょう。それによりエラーやデグレートの発生率を下げることに繋がってきます。
GitとSVNについて
1章ではバージョン管理の重要性についてお伝えしましたが、ここではメジャーなバージョン管理システム「Git」と「SVN」の違いについて簡単にご説明いたします。
※SVNからGitへ移行についての解説は、今回は省かせていただきます。
そもそもGitとは?
「Stack Overflow Developer Survey 2018」の開発者調査レポートによると、世界中で9割近い開発者がバージョン管理システムとしてGitを活用していることが分かりました。

ですが、2005年にGitが誕生するまでは、「SVN」というバージョン管理システムが多くの開発者に使用されていました。
GitとSVNの大きな違い
GitとSVNというワードがこの章では出てきていますが、その違いとは一体何なのでしょう?
▼SVN
ローカルリポジトリが無く、commitをすれば即座に共有リポジトリに反映される。
▼Git
commitすると、一旦ローカルリポジトリに格納され、そこから共有リポジトリに反映する部分を選べる。
つまり、Gitの場合は各作業者の修正部分のみを共有リポジトリに反映することができるので、デグレートの発生を防ぐことができます。少人数のプロジェクトであれば、SVNの方が楽に運用できる場合もありますが、Gitを使いこなせればこれほど便利なツールは無いので、ぜひ導入していきましょう。
Gitブランチを運用する必要性について
せっかくGitを導入してもしっかり活用できていない、その理由はブランチモデルを導入していないからではないでしょうか?
Gitのブランチモデルについて
ブランチモデルとは、開発を進めるにあたって、どのように*ブランチを活用していくかのルールです。Gitではブランチを分けることで、他のブランチに影響を与えずにcommitでき、複数人で別々の機能を開発することができます。
(*ブランチとは、共有リポジトリから分岐させた開発者の作業場のようなものです。)
有名なブランチモデルには「Git-flow」と「GitHub-flow」があります。
「Git-flow」と「GitHub-flow」の違い
▼Git-flow
Git-flowとはオランダのエンジニア、Vincent Driessen氏の"A successful Git branching model" を元にしたワークフローです。
Git-flowでは、役割が決められた5種類のブランチを切り替えながら開発を進めていきます。
※この5つのブランチについては次の章で詳しくご説明いたします。
▼GitHub-flow
Git-flowでは5種類のブランチを使い分けるのに対して、GitHub-flowでは、2種類のブランチ(master、topic)しか使いません。つまりGitHub-flowでは、masterブランチへのマージとリリースはほぼ同義になってきます。
それぞれのメリット、デメリットについては以下のようになります。
それぞれにメリット・デメリットがありますので、現場に合わせたよりよいブランチモデルを使用しましょう。
Gitブランチの運用にルールが必要な理由
ではなぜ、ブランチの運用にルールが必要なのでしょうか?理由はたくさんありますが、大きな理由は以下の3点です。
- ルールがないと、各々の開発者が自由にブランチを切ることでリポジトリのブランチが乱立する。
- ルールがないと、各々の開発者が自由にPush等をしたりして、誰がどこをどれだけ作業したのか状況がつかめなくなる。
- ルールがないと、各々の開発者がmasterブランチ、developブランチにPushをしてしまい、誤って開発途中のソースコードや非公開の情報が本番公開されてしまう。
これらの問題が起こっていることに気づいた時にはもう手遅れで、これらの整理を行うのにかなりの工数がかかってしまいます。
しかし、ブランチモデルを利用することにより、これらの問題を回避することができます。
今回は、開発環境を明確にできることから、当社でもっとも利用されているGit-flowについて、掘り下げて説明をさせていただきます。
※当社の多くのプロジェクトは、開発者が複数おり、検証者(テスター)も複数いることから、GitHub-flowモデルが採用されることは少ないです。
Git-flowを形成する2つのメインブランチと3つのサポートブランチ
ここでは前章でも軽く触れた、Git-flowの5つのブランチのブランチ元、マージ先、それぞれのブランチ命名について解説します。
▼メインブランチ【master、develop】
基本的にはプロジェクトの核になる2つのメインブランチがあります。
この二つのブランチはマージを行うだけのブランチになりますので、直接作業したり、commitすることは避けましょう。
こちらは、重要なブランチになりますので、のGitからサーバへアップするまでの構成図と一緒にご説明させていただきます。
※本プロジェクトでは上の図のようにAmazon API Gateway、Lambdaを利用し、開発者がmasterブランチもしくは、developブランチにマージすることによって閲覧者・検証者側のサーバ側に自動反映(ビルド)され、ユーザー確認できるような構造になっております。
メインブランチの補足事項
・masterブランチ
masterブランチは常に本番環境と同期が取れている必要があります。厳密に言うと、常にリリースが可能な安定したブランチです。
・developブランチ
ブランチ元はmasterブランチで、developブランチは動作や表示などについて最終的な確認が行われるステージング環境と同期が取れている必要があります。
このブランチを中心にブランチを作成していき、開発を進めていきます。
▼サポートブランチ【feature、release、hotfix】
タスクごとに「feature」、「release」、「hotfix」のいずれかブランチを作成し、作業を行います。
これらのブランチはメインブランチから作成され、マージが完了すると削除されます。
サポートブランチの補足事項
・featureブランチ
featureブランチは実際に開発者が作業を行うブランチになります。
ブランチ元、マージ先は共にdevelopでブランチ名は「feature」から始まります。
・releaseブランチ
releaseブランチはリリースをする段階になった時点で使用するブランチです。
ブランチ元はdevelopで、そのブランチでリリース作業(リリースバージョンを示すタグを作成)を行います。リリース作業が完了後、developとmasterの両方にマージします。ブランチ名は「release」から始まります。
・hotfixブランチ
こちらは、リリース後に発生したバグを修正するブランチになります。したがってブランチ元はmasterで、修正が完了後はmasterにマージし、リリース作業を行います。その後、developにマージします。
ブランチ名は「fix」もしくは「hotfix」から始まります。
ブランチの流れは掴めたでしょうか?Git-flowは少し複雑なので、SourceTreeなどのGUIツールを使用して視覚的にブランチの流れを掴むのも一つの方法としていいでしょう。
Digitooでのケーススタディ
さて、ここまでバージョン管理の大切さや、Gitブランチの運用の大切さについて紹介してきましたが、実は本サイト「Digitoo」の制作当初はブランチの運用に厳密なルールを設けていませんでした。
それに伴い、何が起こったか
- マージが確定するまでの間で、同一ファイルの複数作業が発生
- developブランチで作業
- commit履歴の残し方が簡略化しすぎる
結果として、先祖返り、デグレートが多発し、さらにcommit履歴が簡略化されすぎたせいで、どこが原因か追いづらくなりました。そのせいで再修正が多発し、予定工数の2倍の工数がかかるという結果に…
お世辞にもGitを使いこなしているとは言えない状態でした。
そこで本プロジェクトメンバーは、基本に立ち戻り、Git-flowを取り入れ、以下のルールを決め、忠実に従うことにしました。
- 特定のレビュアーを決め、レビュアー以外の人間は、例えどんな小さな修正でもmaster、releaseブランチ、developへmergeすることは避ける。
- commitコメントはルールに従うこと。(後述記載)
1については、先祖返りは勿論のこと、品質担保の面で作業者とレビュアーを決める必要があると考えたため、「開発者→レビュアー」のレビューのワークフローをとることにしました。
2については以下のcommitコメントルールを徹底しました。
基本的な書式
- [プレフィックス]:(コロン){半角スペース}作業内容{半角スペース}Backlog課題キー or No-00(Google Spreadsheet FB番号)
※本プロジェクトではBacklogやGoogleスプレッドシートを使ったタスク管理をしていました。
・プレフィックスの種類
・ 関連課題が無い場合は課題キーを省略可能
・ 作業内容はできるだけ具体的に入れる
・ 作業途中の場合は作業内容の頭に「WIP」を入れる
上記を徹底した結果、先祖返り、デグレートが起こらなくなり、さらに、commit履歴を具体的に記載することで、個人の作業フローが見えやすくなったため、業務の引継ぎなど、スムーズに行うことが可能になりました。
Gitのcommitとブランチ運用の心がけ
ここで、commit時と、ブランチ運用時に心がけておくべき事を、良い例、悪い例を記載しながらまとめていきます。
まとめ
いかがでしたでしょうか?Git-flowは少し複雑で理解するのは容易ではありませんが、各ブランチの役割を把握して運用することで、開発をスムーズに進めることができます。
また、Digitooのインフラ環境のように、Git-flowのブランチと、実際のサーバの本番環境と開発環境を自動連携して、わざわざ、FTPでアップロードのような手間を省き、作業もミスなく楽できるように、AWSなどのクラウドのインフラ環境も整ってきております。
今回の記事では、「Git-flow」について解説しましたが、記事内で解説したように、Gitの運用方法はこれだけではありません。
「GitHub-flow」や「GitLab-flow」などさまざまな運用方法がございますので、開発の規模や状況に合わせて使い分けてみることをお勧めいたします。
今後、インフラ環境などに即した、新しいブランチモデルも生まれると思いますし、当社でも、様々な試行錯誤を繰り返し、最適な開発環境に常に注目していきます。
当社では、Gitでの運用方法の支援をしておりますので、お困りのことがございましたら、お問い合わせくださいますと幸いでございます。
