はじめに
ソフトウェアの開発を行っている多くの開発チームでは、バージョン管理を行っていることでしょう。一方で、「なんとなくバージョン管理を行っているけれど、一回も過去の環境を再現したことがない」「いざという時に、うまく環境を復元できなかった」という話もよく聞きます。皆さんのプロジェクトではバージョン管理はうまく機能しているでしょうか。
この連載では、有効なバージョン管理を行うために必要な「構成管理」という考え方について解説していきます。
まずは、バージョン管理について軽くおさらいしておきましょう。実施に当たっては何らかの管理ツールを活用していると思いますが、ここでは特定のものに依存せず、バージョン管理全般について触れていくことにします。
バージョン管理とは?
バージョン管理とは、ソフトウェア開発の成果物を作成したり変更するたびにその履歴を残すことです。任意の時点の成果物を取り出せるこの仕組みは、開発チームにとって非常に力強いものです。ソースコードなどは成果物の代表例でしょう。
成果物のバージョンを管理していない場合、俗にいう「上書きの問題」が発生する危険性が高まります。上書きの問題とは、端的にいえば「変更の衝突」による作業の損失です。
上書きの問題
例えば、それぞれ異なる目的で開発者Aと開発者Bがソースコードに変更を行うケースを考えてみましょう。2人が変更を行う対象には、共通するソースコードも含まれています。C++のヘッダファイルや、同一クラスの異なるメソッドを編集するケースをイメージしてください。
通常、それぞれの開発者は各自の開発端末にソースコードの一式をコピーし、「開発」「ビルド」「単体テスト」といった作業を行います。一連の作業が完了したら、その結果を開発チームで共有する必要があります。ソフトウェア開発プロジェクトの成果とは、各自の開発端末上のソースコードではなく、チームで共有されたソースコードを指すからです。共有された成果物は、それらは次の開発作業の元となるのです(※)。
各自の開発作業は、できるだけ早期に共有することが重要だと言われています。そうすることにより、各作業で発生する問題をより早期に検知することができます。これをさらに発展させたプラクティスとして継続的インテグレーションがあります。
さて、今回の例でバージョン管理を行っていなければどうなるでしょうか。例えば、ファイルサーバ上でソースファイルを共有していたとしましょう。開発作業が終わったら、最新版のソースコードを共有ディスクトリへコピーするという仕組みです。このケースでは、1つのソースコードに対して複数の開発者が同時に変更を行った時点でアウトです。最悪の場合、ファイルの更新は「後勝ち」となり、先に実施した作業は消えてしまう危険性があります。
バージョン管理の効用
バージョン管理を行っていれば、履歴は保存されるため単純な上書きの問題の多くを防ぐことができます(図1)。
バージョン管理ツールの多くは「上書き問題」に対応できるようになっています。個々のファイルに変更が加えられるたびにバージョンを付与して保管する「バージョン化」だけではありません。ファイルを取得する際(チェックアウト)や、ファイルを共有する(チェックイン、コミット)際に、他の開発者による変更などによってローカルに所有しているファイルとプロジェクトで共有されているファイル(リポジトリ)に差異が生じている場合に、「(コンフリクトの)通知」や、「マージ」を行うことができるようになっています。
ツールの機能だけを見れば、バージョン管理さえ行っていれば開発者同士の上書きの問題は回避できるように思えます。各自の作業も保存されているため、開発者にとっては全幅の信頼を置ける心強い味方だと感じるでしょう。
しかし、本当にそうでしょうか? 本当に使っているだけで安心できるものでしょうか?