WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe       

Subversion : OSS へのローカルな変更を管理する

先日の記事net2ftp の日本語エンコーディング変換対応パッチをご紹介しました。このように既存のオープンソースソフトウェアに変更を加える際に問題となるのが、独自のローカルな変更とソフトウェア本体のアップデートによる変更をいかにしてマージするかです。ソフトウェアの更新頻度にもよりますが、アップデートのたびに手作業で変更を適用するのはとても面倒ですよね。

こんなときも、 Subversion を活用すれば多くの手間を省略できます。もともと複数バージョンのソースファイルを効率よく管理するためのツールですから、まさにうってつけですね。ちょうどいい機会ですので、本日は net2ftp を題材にしてローカルな変更を施したオープンソースソフトウェアを効率的に管理する方法をご紹介しようと思います。

なお、この記事では Subversion がすでにインストールしてあり、基本的な使用方法を理解していることを前提とします。 Subversion の基礎知識については、こちらの記事を参照してください。また、 net2ftp は新規インストールしていますのでご了承ください。

リポジトリを作成

まずは、 net2ftp のソースを格納するためのリポジトリを作成しましょう。

svnadmin create <リポジトリのパス>

リポジトリのパスで指定した場所にリポジトリが作成されます。書き込み権限があり、じゅうぶんな空き容量のある場所ならどこでもかまいません。自分しかアクセスしないなら、ホームディレクトリでも大丈夫です。

リポジトリを作成したら、 Subversion の基本的な作法どおりに、ルートディレクトリに "trunk", "tags", "branches" の 3 つのディレクトリを作成しましょう。

svn mkdir -m "Creating top directories." \
    $repos/trunk $repos/tags $repos/branches

上記のコマンドで $reppos という部分は、先ほど作成したリポジトリの URL で置き換えてください。以下同様です。

trunk にファイルをインポート

リポジトリを準備したら、 net2ftp のソースをインポートします。まずは、まったく変更していないソースから始めるのが無難でしょう。 net2ftp のソースをダウンロードし、ホームディレクトリに展開してください。 net2ftp は主なソースはアーカイブの files_to_upload ディレクトリ以下に格納されていますので、インポートのコマンドは以下のようになります。

svn import -m "Importing net2ftp v0.94 into trunk." \
    ~/net2ftp_v0.94/files_to_upload $repos/trunk

これでリポジトリの trunk 以下に net2ftp のソースがインポートされました。

vendor ブランチを作成

vendor ブランチとは、(ローカルな変更が加わっていない)正規のソースコードを格納するブランチです。本格的な開発を行うときは branches とは別に vendor というディレクトリを作り、そこに作成することが多いです。しかし、今回はさほど大きな変更を施すわけではないので、 branches ディレクトリで共用することにしました。 Subversion では単にリポジトリ内でディレクトリをコピーするだけでブランチが作成できます。

svn copy -m "Creating vendor branche." \
    $repos/trunk $repos/branches/vendor

これで、 "$repos/branches/vendor" の URLnet2ftp 用のベンダーブランチができました。後のマージ作業がやりやすいように、タグも作っておきましょう。

svn copy -m "Tagging net2ftp v0.94" \
    $repos/branches/vendor $repos/tags/20070121_v0_94

タグ名の最初に日付を付けるのは私の癖です。こうしておくとリストを取ったときに必ず日付順に並ぶので(^^;。別に必須ではないので、皆さんの分かりやすいタグ名を付けてください。

trunk をチェックアウトする

さあ、ここまでくれば準備完了です。先日ご紹介した net2ftp のインストール方法では、 net2ftp のファイルをインストール先ディレクトリにコピーしましたが、今回は代わりにチェックアウトを行います。

svn checkout $repos/trunk $net2ftp

$net2ftp は net2ftp のインストール先ディレクトリです。これで net2ftp のファイル群が $net2ftp 以下に展開され、同時に Subversion の管理下に入ります。後は必要な設定やコードの変更を施し、コミットしていくことができます。

なお、この方法(インストールディレクトリに直接チェックアウトする方法)は Subversion の管理ディレクトリが Web に公開されてしまうので、そのままでは非常にまずいです。後述する Apache の設定変更を行って、必ず ".svn" ディレクトリへのアクセスを遮断してください。

新バージョンをマージする

ここまでで net2ftpSubversion の管理下に入れることはできました。問題は、将来 net2ftp の新バージョンが公開された際に、いかにしてローカルの変更とマージするかですね。ここでは、仮に net2ftp v0.95 が公開されたと想定して、そのマージ方法をご紹介しようと思います。

svn-load-dirs

さて、まず問題になるのが、新しいバージョンのファイルをどのようにしてリポジトリにインポートするかです。最も単純な方法は、先ほどと同じように "svn import" を使ってしまう方法です。しかし、これだと旧バージョンのファイルとの関係が考慮されないため、リポジトリが無用に肥大化してしまうなど、いろいろと弊害があります。そこで、このようなときに便利なコマンドが Subversion に含まれています。それが svn-load-dirs です。このコマンドは、リポジトリ内のソースと新バージョンのソースを比較し、その変更を適切にリポジトリに反映してくれます。基本的には、以下のような書式で使います。

svn-load-dirs [-t <タグ名>] <ベースURL> <対象URL> <パス>

タグ名
svn-load-dirs はインポートした結果に自動的にタグを付ける機能があります。タグ名はそのタグに付ける名前です。
ベースURL
通常はリポジトリのルートの URL を指定します。上記の自動タグ機能でのコピー先 URL は "<ベースURL>/tags/<タグ名>" になります。
対象URL
新バージョンをインポートする URL です。通常、旧バージョンのソースが存在する URL を指定します。
パス
新バージョンのソースが存在するディレクトリのパスです。

その他のオプションは svn-load-dirs を引数なしで実行すれば表示されますので、そちらでご確認ください。

新バージョンをインポートする

それでは、 svn-load-dirs を利用して新バージョンのソースをインポートしましょう。まず、 net2ftp v0.95 のソースをダウンロードし、先ほどと同様にホームディレクトリに展開します。 v0.94 と同様に files_to_upload ディレクトリにインストール用のファイルがあると仮定すると、以下のコマンドでインポートできます。

svn-load-dirs -t 20070121_v0_95 \
    $repos branches/vendor ~/net2ftp_v0.95/files_to_upload

タグ名は仮ですので、分かりやすい名前に変更してください。これで新バージョンの変更が $repos/branches/vendor 以下にインポートされ、もし新バージョンで削除されたファイルがあれば同様に削除されます。

ソースをマージする

インポートが終了したので、次はいよいよソースのマージを行います。でもその前に、 $net2ftp にコミットしていない変更がないかどうかを確認してください。もし変更が残っていると、マージによる変更とごっちゃになって面倒なことになります。

変更がすべてコミットされていることを確認したら、以下のコマンドで v0.94 から v0.95 への変更をマージします。

svn merge $repos/tags/20070121_v0_94 $repos/branches/vendor $net2ftp

もしローカルな変更と v0.94 から v0.95 への変更が重なっているとコンフリクトが発生します。その際は手動でマージして、 resolve してください。その後、動作確認して正しく動作するようなら、コミットしてマージ作業終了です。

.svn ディレクトリへのアクセス制限

前述の通り、今回ご紹介した方法では Subversion が各ディレクトリに作成する ".svn" ディレクトリが公開されてしまうため、セキュリティー的に好ましくありません。それを防ぐため、 Apache の設定を変更しましょう。 Apache には正規表現にマッチするディレクトリに対してアクセス制御をする機能があるので、それを使ってすべての ".svn" ディレクトリを一括してアクセス禁止にします。具体的には、 http.conf かそれに相当する設定ファイルに、以下の設定を記述します。

<Directory ~ "^$net2ftp/.*/\.svn">
    Order deny,allow
    Deny from all
    AllowOverride None
</Directory>

$net2ftp を net2ftp のインストールディレクトリに置き換えるのを忘れないでください。これを設定して Apache を再起動した後、ブラウザから ".svn" 以下のファイルにアクセスしてエラーになるのを確認しておきましょう。

以上、今回は net2ftp を題材にして、ローカルの変更と正規バージョンのアップデート内容を効率的にマージする方法をご紹介しました。とくに Web アプリケーションには気軽にカスタマイズできるものが多いので、今回の方法が役に立つ場面も多々あるかと思います。ソースレベルでカスタマイズできることこそがオープンソースソフトウェアを使う最大の利点ですので、皆さんも活用してみてください!

関連記事

この記事にコメントする

Recommendations
Books
「Closure Library」の入門書です。
詳しくはこちらの記事をどうぞ!
Categories
Recent Articles