バージョン管理システム(版管理システム)
バージョン管理システム(版管理システムとも呼ばれる)は,ソースコードをはじめとしたファイルの履歴をバージョンとして保存・管理するためのシステムである.誰が・いつ・どのファイルを・どう編集したかを記録することで,様々なメリットを享受することができる.
1970年代以前,あるいは現在でも少数ながら存在するバージョン管理システムを利用せずにファイルを管理する組織において,複数人でソフトウェア開発を行うためには,下図のようにネットワークドライブ等にファイルを置き,共有しながら開発することになる.
このような状況では,下記に示すような様々な問題が発生することが知られている.
P1. どのファイルを誰がいつどのような目的で変更したのか分からない
ソフトウェア開発において,開発者はバグ修正や機能追加等様々な理由でソースコードを修正する.バージョン管理システムを利用せずにソースコードの修正作業を行うと,誰がソースコードのどの部分を,いつどのような理由で修正したのかを把握することは非常に困難である.
P2. ファイルを間違えてアップロードしてしまった場合に簡単にやり直せない
開発を行っていくうえで,間違ったファイルのアップロードが行われることがある.間違いにすぐ気づくことができれば良いが,気づかなかった場合,後で遡って間違ったファイルだけを差し戻すことは非常に難しい.
P3. ファイルの変更箇所が他の人と被っていた場合でも,それに気づけず上書きしてしまう
特定のファイルを複数人で同時に開発していた場合,例えば上図の開発者A,Bが共通のJavaファイル「hoge.java」をダウンロードし,編集していたとする.このとき,変更後のファイルをAがアップロードした後につづいてBがアップロードすると,Aの編集した内容をBの編集内容が上書きしてしまう.
このような問題に対応することを目的として,バージョン管理システムが利用されている.
一般的に,バージョン管理システムは上図のようにリポジトリと呼ばれるデータベースに誰が・いつ・どのファイルをどう編集したのか,といった情報を保持する.ユーザが編集したファイルをリポジトリに登録する作業のことをコミット(Commit),任意のバージョンのファイルあるいはファイル群をリポジトリから取得することをチェックアウト(Checkout)と呼ぶ. ユーザはリポジトリを操作することで,ファイルの変更履歴の確認や過去のバージョンへの差し戻しといった様々な処理を行うことができる. また,バージョン管理システムでは,P3で述べたような複数の開発者が特定のファイルを同時に編集し,それをCommitしたとき,Conflict(競合)という形でP3で述べたような編集作業の意図しない重なりを検出してくれる.
以降では,これまで開発・利用されてきたバージョン管理システムの簡単な歴史とその種類や特徴について紹介する.
版管理システムの歴史
単一ファイル・単一ユーザを対象としたRCS
1980年代にリリースされたRCS(Revision Control System)はローカルマシンにあるファイルのバージョンを単一のユーザが管理することを目的として作られた.RCSを利用することで,そのユーザがいつどのような変更をファイルに加えたのかを把握することが可能となった.一方で,複数人での利用を想定しておらず,P3で述べたような変更箇所の競合に対応することができなかったりといった課題があった.
複数ユーザを対象としたファイルベースでのバージョン管理を行うCVS
1990年代に入り,ネットワークでの利用を前提としたクライアント・サーバ型のバージョン管理システムとしてCVS(Concurrent Versions System)がOSS(Open Source Software)コミュニティによって開発された.CVSではサーバにリポジトリが配置されており,ユーザはネットワークを介してCVSのリポジトリにアクセスし,CommitやCheckoutを行うことができる.複数ユーザによる利用を考慮しており,複数人が共通のファイルを編集し,Commitした場合でも,Conflict(競合)が発生したことが分かるため,P3で述べた意図しない上書きを防ぐことが可能となった.
一方で,CVSはファイル単位でバージョンを管理しており,ある開発者が関連する複数のファイルを同時期に編集していたとしても,CVSリポジトリ上ではそれが分からないという問題があった.例えば下図のように複数種類のファイルがCommitされているCVSリポジトリがあったとする.CVSでは,ファイルごとにバージョン番号がつけられるため,JavaファイルのどのバージョンとXMLファイルのどのバージョンが一緒に開発されたかはファイルごとのバージョン番号を見ても分からない.結果として,バグ修正等で複数のファイルを修正したときに,どのファイル群がバグ修正に関連するものなのかを特定するといった作業が困難なものとなってしまっていた.
複数ファイルからなるチェンジセットベースでのバージョン管理を行うSubversion
2000年代に入り,Subversionと呼ばれる現在最も普及しているバージョン管理システムが開発された.SubversionはCVSと同様複数ユーザを対象としたクライアント・サーバ型システムとして構築されており,ユーザはネットワークを介してSubversionリポジトリにアクセスし,Checkout(リポジトリからのファイルの取得)やCommit(変更したファイルのリポジトリへの登録)を行うことができる. Subversionの最大の特徴はある開発者が複数ファイルを同時に変更し,同時にCommitを行ったときに,その複数ファイルの群をチェンジセットと呼ばれる単位で管理することが出来る機能である.下図に示すように,Subversionリポジトリは同時にCommitされた複数のファイルをまとめて一つのチェンジセットとして管理し,バージョン番号を割り振る.そのため,チェンジセット単位でファイル群の変更履歴を把握できるようになった.一方で,Subversionリポジトリがクライアント・サーバ型であるために,CommitやCheck outを行う際には必ずローカルPCがネットワークに接続されていなければならないことやCommitやCheck outを毎回ネットワーク越しに行うために遅いという点が問題として挙げられるようになってきた.
分散型のバージョン管理を実現したGit
これまでのバージョン管理システムはクライアント・サーバ型,すなわちサーバ側に中央リポジトリを一つ持つタイプとして開発されていた. 2005年に開発されたGitと呼ばれるバージョン管理システムではリポジトリは中央に一つではなく,各ユーザがローカルPCにそれぞれリポジトリを持つことが可能となった.このようなバージョン管理システムのことを分散バージョン管理システムと呼ぶ.
分散バージョン管理システムでは,CVSやSubversionのような集中型バージョン管理システムとは異なり,下図に示すようにサーバにあるリポジトリ(リモートリポジトリ,あるいは originと呼ぶ)から,特定のファイルをCheckoutするのではなく,リポジトリそのものをダウンロード(Cloneと呼ぶ)する.これによってユーザは各自のローカルPC上にリポジトリ(ローカルリポジトリと呼ぶ)を持つことができる. ユーザが開発を行う際には,ローカルリポジトリから必要なファイルをCheckoutし,開発を行ってから変更内容をローカルリポジトリにCommitする.Commitした内容を他ユーザと共有する場合は,定期的にローカルリポジトリの内容をリモートリポジトリにアップロード(Push)する. これにより,サーバにアップロード(Push)するときだけネットワークに繋がっていればよく,通常のリポジトリへのCommitはローカルPCがネットワークに繋がっていなくとも行える.結果として,ユーザの好きなタイミングで迅速に(ネットワークを介さないため)作業内容をCommitすることができる.Commitを行いやすくなることで,Commitのし忘れによる作業内容の喪失を防ぎ,ローカルPCでの試験的な実装の試行などもやりやすくなる.
問題
バージョン管理システムについて下記の問題に解答せよ.
- バージョン管理システムを利用することによるメリットを3つ以上述べよ.
- RCSとCVSの違いについて,何が改善されたかを中心に説明せよ
- CVSとSubversionの違いについて,何が改善されたかを中心に説明せよ
- SubversionとGitの違いについて,何が改善されたかを中心に説明せよ
- Gitの下記キーワード(コマンド)が何をするためのものなのか,「ローカルリポジトリ」「リモートリポジトリ」という言葉を利用して説明せよ.
- Push
- Clone
- Commit
- Checkout