現在の構成管理サーバーはGitが中心になりつつあります。
構成管理サーバーにはいろんな機能や使い方がありますが、それらの構造やなぜそういった機能が必要になったのかなど、ソース管理の歴史をさかのぼりながら説明します。
ファイルサーバー
20年ぐらい前の開発はファイルサーバー(共有フォルダ)でソースを管理していました。
一つのフォルダに置かれたソースを最新版として、フォルダ全体をローカルにコピーし、担当するプログラムを作成ししたらファイルサーバーにコピーするという手順で作業を行っていました。
ファイルサーバーとローカルのフォルダ構成が全く同じのため、コピーや削除を行うときに間違えて修正したファイルを古いもので上書いてしまったり、削除してしまう事故が発生するため、ファイルサーバーの更新を行うときは慎重に行う必要がりました。
また、過去の状態を見たい場合は、ファイルサーバーのフォルダをバックアップしたものを見るしかなく、バックアップのタイミングが悪いと以前の状態のファイルを見ることができないということもよく発生しました。
VSS
こういった開発時の問題を解消するため、ソース管理ツール(構成管理ツール)が使われるようになりました。
最初に作られたのが、Microsoft Visual Source Safe(VSS)だったと思います。
VSSの仕組みは、ソース管理サーバーにVSSサーバーを立て、VSSサーバー上にプロジェクトを作成し、そこに管理したいファイルをアップ(チェックイン)します。
ファイルを編集したい場合はチェックアウトし、編集が終わったらチェックインします。
こうすることで、過去の状態のファイルはすべて履歴として管理され、前回の状態との比較したり、変更を元に戻したりなどを行うことができます。
しかし、VSSには以下のような問題がありました。
- 誰かがチェックアウトしているファイルは他の人が編集できない。(チェックインを忘れると誰も触れないファイルができる)
- サーバー、クライアント、それぞれにライセンス料が必要
CVS
その後、CVSが使用されるようになりました。
CSVの特徴は以下の通り
- サーバー、クライアント、いずれもフリー
- チェックアウトという概念がなく、いつでも修正できる
- 他の人と同じファイルを編集した場合は手動でマージすることでファイルのロールバックを回避する
CVSはVSSのようにチェックアウトという行為を行わずに、いつでもファイルの更新が可能です。
更新したファイルはコミットすることでサーバーに更新されます。
コミットしたとき、すでにサーバー側のファイルが更新されている場合はコンフリクトとして扱われ、
サーバー側とローカル側のファイルを比較した画面が表示され、手動でマージ作業を行うようになっています。
無償でファイルをロックすることがないため、多くの人に使われました。
しかし、CVSにも以下の問題がありました。
- ファイルごとに履歴を管理しているため、複数ファイルを同時にコミットした場合でもプロジェクトを元の状態に戻すにはファイルごとに戻す必要がある
SVN
CVSの後継としてSVNが使用されるようになりました。
SVNの特徴は以下の通り
- 履歴の管理やコミットの考え方はCVSと同じ
- コミット単位に履歴が作られ、複数ファイルの更新を一つの履歴として管理する
複数ファイルのコミットを同時に行うことで、一つの履歴として扱われるようになり、簡単に以前の状態に戻すことができるようになりました。
リポジトリ全体のファイル構成を履歴として扱うことから「構成管理」と呼ばれるようになりました。(いまだに違和感がありますが)
また、履歴を「断面」と表現されるようになりました。
CVSの問題が解決されたため、長い期間、多くの人に利用されました。
このころから、EclipseやVisualStudio.netなどの多くの開発ツールとの連携もサポートされるようになったことも利用者が増えた理由の一つと思います。
SVNが利用される頃にリポジトリ構造の標準化が行われるようになりました。
これはリポジトリ全体を履歴管理できるSVNだから可能な考え方です。
標準構成といってもフォルダを分けているだけで、SVNに機能があるわけではありません。
SVNのリポジトリの標準構成は以下のようなものです。
現場ごとの運用の違いで若干の差はありましたが、おおよそ、下記のような構成で使われます。
trunc | 最新ソース |
branch | 開発中ソース、リリースごとのソース |
tag | リリースごとの差分ソース |
通常の開発はbranchで実施します。(新規の場合はtruncで行います。)
同じシステムに対する複数の改造案件が同時に実施される場合はbranchを2つ作成し、それぞれに開発を行い、最後にマージしてtruncにコミット、tagを作成してリリースします。
開発完了後、問題が発覚した場合はbranchの履歴などから原因の特定を行います。
(truncの履歴にはリリースの履歴しかないから)
長く使われたSVNですが、やはり、以下のような問題がありました。
- マージが半自動で行われるため、コンフリクトが発生した場合、手間がかかる
- branchであっても履歴が公式なもの(リリース履歴)として扱われるため個人の履歴管理として利用できない
- むやみにコミットできないため、最新ソースがローカルにしか存在しないことが多くなり、マシントラブルで消えてしまうリスクがある
Git
最近ではSVNの後継のGitが使われるようになりました。
Gitの特徴は以下の通り
- 履歴の管理やコミットの考え方はSVNと同じ(システムの構造やリポジトリツリーとかの機能は全く別物ですが)
- 基本的にローカルにクローン(コピー)を作成してファイルを更新する
- プッシュのタイミングでサーバーに更新されるが、それまでのコミットはローカルの履歴で管理される
- ファイルマージはほぼ自動化されているが、手動マージが必要な場合のみコンフリクトが発生する
- ブランチを作成する前提のシステムで、SVNのようにフォルダでの管理ではなく、ブランチ管理を機能として持っている
- リポジトリパターン(ブランチの構成パターン)は用途に応じて使い分ける
ローカルも履歴管理されるため、サーバーにアクセスしなくても過去の状態に戻すことが可能です。
プッシュすることでローカルの履歴もサーバーにアップされてしまうので、履歴が汚れることはSVNとあまり変わりません。
そのあたりを考慮してfeatureブランチを利用するリポジトリパターンが用いられているようです。
SVNに比べて洗練され、機能も充実しています。
しかし、まだ使われるようになってから日が浅いのでリポジトリパターンの試行錯誤が行われている感じです。
現時点でのGitの問題は以下の通り
- リポジトリパターンが複雑で使いこなせない
- 高機能化、自動化が進んだため、難解
まとめ
Gitの登場で機能的にはかなり充実してきたと思います。
しかし、機能も使い方も複雑になりすぎていてかなり敷居の高いものになってしまっていることも否定できないです。
自動化が進んだことで楽にはなってますが、何がどう変わるのかは把握しておきたい気もします。
まだまだ課題が多くあるように思うので、別のソース管理ツールが作られるように思います。
追随するのが大変ですね。