Tue, 30 Jul
Google の巨大レポジトリとブランチ無し運用

GTAC 2013 Opening Keynote の Evolution from Quality Assurance to Test Engineering (スライド) を見た。

スライドの7ページ目 によると、Google では 15,000 あまりの開発者が、40 あまりの拠点に分散している。そして、彼らはひとつの巨大なレポジトリで、ブランチなしに開発しているらしい。

  • Single monolithic code tree with mixed langauge code
    • Over 100 million lines of code.
    • 50% of code changes monthly.
  • Development on one branch - submissions at head

講演ではこの理由について

One of the benefit is that we don’t have to support a thousand different versions of libraries for different applications. Everything runs at head.

とだけ説明されている。

Still All On One Server: Perforce at Scale などを見るかぎり、Google のメインレポジトリは Perforce だと思う。Perforce は Subversion のようにサブツリーのチェックアウトができるので、複数のプロジェクトがひとつのレポジトリに同居するのは、そこまで珍しいことではない。

ただ、bk ノートの 巨大リポジトリの世界

というのは前置きで、私は巨大リポジトリのファンだ。巨大レポジトリにはいろいろメリットがあるが、一番大きいのは「呼び出し側のコードをまとめて変更できる」ことだと思う。これは YAGNI と premature complication の中で少しだけ触れたテーマだ。

向井さんのはなし を読むと

会社のコードでは、コードベースは基本的に統一されていて、全員が同じレポジトリを触る構成なため、大きな問題がない、というのもある。Chromiumも自前のベースライブラリを持ち、様々な機能ごとのモジュールがあるが、全部同じレポジトリにコミットしている。そうすると、「このコミット移行はこういうことになるんで、ヨロ」というメールを一本書いて、ひとつのコミットで関連する問題をまとめて直す、といったことが可能になる。

巨大レポジトリは「運用上の都合」から、その利点が認識され、Chromium のような Google 主導のオープンソースソフトウェアにも引き継がれているようで面白い。

ブランチ無し開発は、Flickr もやっている ことが知られている。

Flickr is somewhat unique in that it uses a code repository with no branches; everything is checked into head, and head is pushed to production several times a day.

昔にこれを読んだときには「どの会社にも、社員はうけいれてるけど、外から見たら変な風習があるのだなあ」くらいに思っていたんだけど、最近になってやっと必要性がわかってきた。これについては Comparators の ブランチ vs. フラグ を読むのをおすすめしたい。

2013年8月17日追記

Google でも、Chrome にはリリースブランチめいたものはあるようだ。chrome/releases の下にはメタデータしか無いけど、chrome/branches にはふつうにブランチが切られている。なお、例にあげた 28.0.1500.95 と 1500 は今日時点での Mac むけ Stable チャンネルに対応していて、これは OmahaProxy CSV Viewer をみるとわかる。Omaha というのは、Google の Windows むけソフトウェアアップデーターのことらしい。

Chrome のリリースについては chromium.org にある Release process という文章が詳しい。Chrome は、Google のなかでは例外的なソフトウェアだと思う。サーバーサイドで完結せず、Chromium という形で多くの部分がオープンに開発されているからだ。ただ、ここでも

Most of our features are developed directly on the master branch and disabled just after forking a release branch if not stable worthy.

とされている。

巨大レポジトリは、Git のようなレポジトリ全体のクローンを要求するバージョン管理システムだとやりづらいし、Bundler のような依存性を管理する仕組みにくらべると柔軟性が低い。独立して開発がすすむ小さなレポジトリを、柔軟なかたちで (このレポジトリではライブラリの最新版をおっかける、ここではメジャーバージョン固定、ここではマイナーバージョンまで固定、といったふうに) 組み合わせられたほうが良さそうにみえる。

オープンソースソフトウェアでは、こうする意外に方法が無い。ライブラリの作者が、自分のライブラリを使っている世界中の全てのソースコードを直すのは不可能だ。でも、企業の中なら、呼び出し側を一気に変更することも、ある程度は可能なんじゃないだろうか。

技術的負債の例えをつかうと、Google の巨大レポジトリとブランチ無し運用は、ある種の無借金経営といえると思う。依存しているライブラリのバージョン固定や、レポジトリのブランチで得られる安定性は、借金なのだ。ほとんどの場合、ライブラリはいつかアップグレードしなくてはいけないし、ブランチはいつかマージしなくてはいけない。払わなくてはいけない利子は時間がたつにつれて増えていく。そう考えると、Google の一見すると変な、分割統治の逆をいくようなやり方にも、それなりに利点はあるように思う。