連載
» 2013年05月20日 18時00分 公開

DevOps時代の開発者のための構成管理入門(3):知らないと現場で困るバージョン管理システムの基礎知識 (3/3)

[江口和宏, 山本竜三,株式会社ヌーラボ]
前のページへ 1|2|3       

4つのブランチを使用するBacklogチームのブランチ運用

 まず、BacklogではASP版とパッケージ版の2つのエディションを提供しています。これに加えて、開発中の機能を組み込んだベータ版の環境を用意してヌーラボ社内で使用しています。そのため、メインブランチとしては以下の4つのブランチを使用しています。

  1. 「master」ブランチ
  2. 「beta」ブランチ
  3. 「develop」ブランチ
  4. 「package-master」ブランチ

「develop」ブランチ

 developブランチは普段の開発を行うためのブランチです。またリリースも、このブランチから直接行っています。リリース時にはタグを追加して、どのコミットの時点でリリースしたかが、後から分かるようにしています。

「beta」ブランチ

 betaブランチはJenkinsを使用してテスト用環境やヌーラボ社内で普段使う環境にデプロイできるようになっているブランチです。テスト環境で動作を確認したり、新機能などの「ドッグフーディング」を行う場合はdevelopブランチをbetaブランチにマージするか、直接betaブランチ上で変更を行います。

 betaブランチで直接変更を行った場合は、後からdevelopにマージして取り込みます。

「Non Fast-Forwardマージ」と「Fast-Forwardマージ」

 開発は基本的にフィーチャーブランチを作成して行い、ブランチ名にはBacklogの課題キー名を使用して課題とひも付けています。フィーチャーブランチのマージは「ブランチがあったことが分かりやすいように」という理由で「Non Fast-Forwardマージ」を行うようにしていました。

 しかし、コミット数の少ないブランチも全てNon Fast-Forwardマージを行っていると、並行して進んでいるブランチが多くなったときに履歴のネットワーク図が見づらくなってしまうことが分かったため、現在は基本的に「Fast-Forwardマージ」を行うようにしています。

 また、フィーチャーブランチを後からフィーチャートグルでの開発に切り替えた例もあります。現在開発を進めているサブタスク機能の場合では、影響範囲が大きいためサブタスク専用のブランチで開発を進めていました。

 ある程度開発が進んだので、ヌーラボ社内で実際にサブタスク機能を使ってみることになりましたが、そのためにはメインブランチにマージする必要がありました。そこで、メインブランチ上ではサブタスク機能の開発と、その他の機能の開発とリリースを同時に進められるように、データベース上のフラグでサブタスク機能を無効にできるようにしてからマージしました。

「package-master」ブランチと「master」ブランチ

 package-masterブランチはパッケージ版の開発を行うためのブランチです。パッケージ版専用機能の開発など、ASP版には必要のない変更のみを行うので、masterブランチにはマージしません。パッケージ版とASP版の両方に必要な変更は、developブランチで行ってから、masterブランチを経由してpackage-masterブランチに取り込みます。

Backlogチームのブランチ事情

コラム Subversion→Git移行時のブランチ運用の試行錯誤


 上で紹介した現在のブランチ運用にたどり着くまでには、いくつもの失敗や試行錯誤がありました(現在もより良い運用を求めて試行錯誤を続けておりますが)。その一例として、ASP版(master)の変更をパッケージ版(package-master)へ適用する方法での失敗について紹介します。


Subversion時代は「マージトラッキング」


 以前Subversionを使っていたころ、Subversionの「マージトラッキング」機能を使い、ASP版の変更点のうちパッケージ版に必要なもの(コミット)を確認しながらマージしていました。マージトラッキング機能のおかげで、「どこは適用済みで、どこは未適用なのか」は把握できており、安心してマージできました。


「マージトラッキング」のつもりでGitの「cherry-pick」


 Gitに切り替え後、Subversionのマージトラッキング機能と同じつもりでGitの「cherry-pick」を使い適用を進めていたのですが、cherry-pickした場合、変更内容は同じでもコミット自体は別のものとなってしまうため、どの変更内容が適用済みなのか分からなってしまう状況となり、非常に不安で危険な状態に陥いってしまいました。


 そこで、やや大掛かりにはなりましたが、パッケージ版ブランチpackage-masterはいったん捨ててしまい、あらためてmasterからブランチを作成しパッケージ版固有の変更を適用し直すところからやり直しました。


 そして、cherry-pickは本当に特別な場合のみの利用に限定し、ブランチ間のgit mergeで変更内容を適用する方針に変更しました。


ビルドやフィーチャートグルによる機能のオン/オフを実現するよう努力


 もしパッケージ版で不要な変更内容がある場合は、そのコミットのみgit revertするようにしています。また、ASP版(master)とパッケージ版(package-master)のソースコードの違いを極力小さくし、ビルドやフィーチャートグルによる機能のオン/オフを実現するよう努力しています。


 SubversionのマージトラッキングとGitのcherry-pickは概念的には同じように見えても各バージョン管理システムでのブランチのそもそものコンセプトの違いがあり、間違った運用をしてしまいましたが、Gitのブランチについて理解が深まったり、ブランチの運用やビルド方法、ソースコードの構成など、改善する良い機会となりました。


Gitのフックによる、バージョン管理システムと他システムの連携

 多くのバージョン管理システムでは、コミットやプッシュなどのアクションが発生した時に特定の処理を実行させるフックと呼ばれる仕組みを備えています。

 また、GitHubやBitbucket、Backlogなどのバージョン管理システムにホスティングしているWebサービスの場合は、あらかじめ登録したURLでプッシュが発生したことの通知を受け取れるような仕組みを提供しているところもあります。

 このフックを活用すると、他システムと連携して、さまざまなことが可能です。

 Gitのフックは「クライアントフック」「サーバサイドフック」の2種類のフックに分けられます。

クライアントフック

 クライアントフックでは、コミットメッセージの入力を求められる直前に実行される「pre-commitフック」や、コミットか完全に終了した後に実行される「post-commitフック」など、さまざまなタイミングで任意のスクリプトを実行できます。

 pre-commitフックでは、スクリプトからの戻り値によってコミットを中断することもできます。そのためコーディングスタイルの検査などを行い、結果に応じてコミットを中断させることで適切でないコードのコミットを防ぐといったようなことが実現できます。

サーバサイドフック

 サーバサイドフックでは、プッシュを受け取った直後に実行される「pre-receiveフック」や、プッシュによる処理が終了した後に行われる「post-receiveフック」などがあります。

 このフック利用して、プッシュのあったタイミングでITS/BTSのチケットの状態を変更する、チケットにコメントを追加する、「Jenkins」などのCIツールを利用して自動テストを実行するなどの処理ができます。

 pre-receiveフックでは、pre-commitフックと同じくプッシュを中断できるので、適切でないコミットがプッシュされることを防いだり、アクセス権限のないファイルへのアクセスを拒否するといったことが実現できます。

次回は、CI――継続的な統合

 今回は構成管理の肝となるバージョン管理とその運用について紹介しました。次回は「継続的な統合(Continuous Integration)」です。お楽しみに。

著者プロフィール


江口和宏

株式会社ヌーラボにて「Backlog」の開発・運用や「サルでもわかるGit入門」の執筆などに携わる。模型制作が趣味のソフトウェア開発者。京都在住。


山本竜三

株式会社ヌーラボにて「Backlog」の開発や「Cacoo」のインフラ運用などを行う。福岡在住。


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。