人とか機械とか

デジタルガジェットやコンピュータについてのブログです。

超初心者がバージョン管理システムを導入してみた

バージョン管理システムを全く使った事がない僕が、TortoiseSVNを使い始めた作業メモです。
まだ1ヶ月くらいですが。

SVNの本格的なマニュアルは、なんだか難しいことも含めて書きすぎてよくわからないので、とりあえず自分がいま運用しているのに必要な知識だけをまとめました。




バージョン管理とは何か


プログラムのソースコードの変更履歴を管理するしくみです。

代表的なバージョン管理システムを挙げると、

  • 古いの  → CVS (たぶん10年以上の歴史がある)
  • 実績あるの→ Subversion (SVNと略す。10年くらいの歴史がある)
  • 新しいの → Bazaar (CVSSVNとちがって分散型。歴史は5年くらいと浅いが人気ある)
  • MS専用  → VisualSourceSafe (VSSと略す。有料だしよく知らない)

があるらしいです。


CVSSVNは集中型と呼ばれ、サーバにリポジトリを置き、クライアントからサーバのリポジトリにアクセスする形式です。CVSSVNの違いは僕にはよくわかりません。何か問題点が解決されているらしいです。
Bazaarなどは分散型と呼ばれ、各マシンにそれぞれリポジトリがあり、リポジトリ同士で整合をとりあう形式です。しかしSVNサーバのリポジトリにアクセスすることも可能だったりと、互換性もあります。

分散型でもコマンド体系がCVS/SVN系のものもあれば、まったく互換性のない独自コマンド体系のものもあります。




僕の状況


 僕はいままで、プロジェクト(ソースファイル一式)をzipに固めて扱っていました。でも、なんだか時代遅れなのかなあと思って、バージョン管理システム使おうと思いました。それに、使い方を覚えて損はないと思ったからです。

とりあえずTortoiseSVNにしました。理由は、隣の人が使ってたからと、あと、サーバいらなくてローカルマシン1台のスタンドアロンで使えるからです。それに、TortoiseSVN自体に長い実績があるからです。

開発環境はWindows上で、とりあえず自分のローカルマシンで一人で使うものです。
ちなみにエディタはsakuraエディタです。




TortoiseSVNの作業の流れ


バージョン管理はリポジトリ(repository)という単位で行います。IDEのプロジェクトみたいなモノです。このリポジトリの中に、ソースコードのすべての履歴が入ることになります。本来Subversionはクライアント・サーバ型なのでサーバを用意してそこにリポジトリを置くのが一番いいのですが、めんどくさいのでローカルマシンで済ませたいので、ローカルマシンにリポジトリを作ります。


まずリポジトリを作って、その中にディレクトリをつくったり、ソースファイルをインポート(import)したりして、リポジトリの基本構造(リポジトリレイアウト)を作ります。/trunkは開発の最前線のものを入れ、/branchesの下に枝分かれバージョンのディレクトリを作成して枝分かれする、というのが一般的らしいです。/tagsというのはbranchesとどう違うかよくわかりません。
  http://tortoisesvn.net/docs/release/TortoiseSVN_ja/tsvn-repository.html


リポジトリに対するすべての操作(コミット、ディレクトリやファイルの作成・削除・名前変更)は履歴に残り、1つの履歴をリビジョン(revision)と呼びます。リポジトリのリビジョン番号がどんどん増えていきます。最新のリビジョンのことをヘッド(head)と呼ぶらしいです。また、リビジョンには、「リポジトリのリビジョン」と、「ファイル毎のリビジョン」があります。


リポジトリができたら、そのリポジトリ内のファイルを直接編集するわけにはいかないので、リポジトリのリビジョンを選んでコピーしてきます。このコピーすることをチェックアウト(check out)と呼び、チェックアウトしたものを作業コピー(working copy)と呼びます。


作業コピーを編集して、それをリポジトリへ保存したいと思ったら、コミット(commit)します。コミットする内容は、ふつうはリポジトリに存在するファイルの変更です。ですが、ファイルの追加とか削除もできます。コミットするとリポジトリのリビジョンが増えて、履歴に残ります。作業コピーは要らなくなったらさっさと消します。残ってるとあとで「何だっけこれ?」となったりするのでよくないです。


メニューの「ログの表示」というところで、リポジトリのリビジョン履歴が表示できます。リビジョン毎にどのファイルが更新・追加・削除されたかがわかります。リビジョンを選んで比較することもできます。




ログメッセージ


リビジョンに対してメッセージを残せます。コミットするときに記入します。
ですが、後からリビジョンに対してメッセージを書き換えるにはリポジトリの設定を変更しないとダメらしいです。デフォルトだと変更不可能になっています。で、なんかリポジトリに対して発生したイベントにフックしてスクリプトが動く仕組みがあるらしいです。

リポジトリ内のhooksディレクトリ内に "pre-revprop-change.bat"という名前のファイル作って、中身は以下のようにする。

@echo off
exit 0

これでメッセージを書き換えられるようになります。このメッセージの編集は履歴が残らず上書きされていくので注意すること。ちなみに、hooksディレクトリに入って居る.tmplというファイルは、UNIX向けのシェルスクリプトのテンプレートなので、windows環境でローカルリポジトリとして運用するぶんには、そのまま使うことはできません。




エクスポート


エクスプローラ上のリポジトリのディレクトリ、リポジトリブラウザ、ログメッセージウィンドウ、などの右クリックメニューから「エクスポート」を選ぶと、SVN管理下にある作業コピーのチェックアウトではなく、ふつうのファイルとして吐き出すことができる。作業コピーとの違いは、ファイルの更新日付が元ファイルのままになる事と、隠しディレクトリの".svn"がない点。

ちなみに、エクスプローラから作業コピーを右クリックしてのエクスポートだと、また意味が違ってくる。これをやるとファイルの更新日付が作業コピーの日付になる。

ちなみに、リポジトリへファイルをインポートしたとき、そのファイルの更新日時はインポートした日付になる。




運用方針

長時間席を離れるときには必ずコミットし、作業コピーを削除する。

ソースの編集が半端だけど帰りたいとか会議があるとかいう場合は、とりあえずコミットしておきます。朝出社して、なんかコミットしてない作業コピーが残ってると、あれこれなんだっけ?となります。作業の流れを固定化したほうが間違いがないです。


ログメッセージにタグをつける

 ビルドすら通していないものは無印、とりあえずビルドを通したリビジョンには[build]、動作確認したリビジョンは節目を表す[knot]、バージョンをつけて外部にリリースしたものを[release]、とか言うような自分ルールでなんとなく管理しています。いまのところ。


細かくコミットする

 リビジョン番号が増えたところで、外部リリースするバージョン番号が増えるわけではありません。このため、リビジョン番号が増えることに気力を使う必要はありません。このため、「1機能を追加した」とか、「1バグを修正した」とかいう単位でコミットして問題ないです。ある程度細かいほうが、あとから管理やバグ追跡しやすかったりもします。その「1バグ修正」や「1機能追加」には、1ファイルではなく複数ファイルにわたって変更が入ることもあるので、なおさらです。




昔のやり方よりも良くなった点


細かくリビジョンが作れる点。「1機能の追加」や「1バグの修正」をするとき、複数のソースファイルに変更が及ぶことがある。そういった変更が複数に重なって「1バージョンのzip」という単位で扱っていたため、どの変更がどの機能・バグに対応しているのかが分かりづらかった。このため、「1機能追加で1リビジョン」、「1バグ修正で1リビジョン」にしてしまえばそれが明確になって管理しやすい。

昔のやり方で細かくリビジョンを残そうものならzipアーカイブが山のようにできてしまう。しかもリビジョン間でソースの比較をしようとしてもいちいち解凍するのがめんどくさい。さらに、合計のファイルサイズも大きくなる。事実上、管理が不可能だと思う。

ソースコード全体を横断するように #ifdef のコンパイルスイッチを作ったりしていたが、そういうのはbranchesでブランチ(枝分かれ)したほうがスマートである。




今後


ブランチの仕方がいまいちわからないので、できるようになって活用したいです。

バージョン管理システムは、バグ追跡システムと連携できたりするらしいので、そのへんもやってみたいです。



追記

なぜいままでSVNを使わなかったのか、知り合いと話して考えた。

  • 一人でzip管理であっても、辛うじてなんとか把握できる範囲の開発規模だったから。
  • 小規模な開発だから。あんまり複数人でソースをいじらないから。

いじったとしてもファイル分けての分担作業だったり、マージツールでがんばってマージしてたりした。

  • ソースコード管理システムを使っている人が身近にいなかったから。

上司はCVSを導入しようと検討してたことがあったみたいだけど、結局導入しなかった。

こういうのを開発手法のガラパゴス化って言うんですかね。SVN使えばラクで安全でメジャーなことなのに、それを使わないでやりくりする謎の無駄な努力と技術が身についている。バッドノウハウ