unoh.github.com

SVN を使いやすくするシェルスクリプト

Mon Aug 21 03:02:36 -0700 2006

こんばんは、naoya です。
ウノウでは、プログラムのソースコード管理に SVN を使っていますが、日々の開発の中でずっと SVN コマンドを使い続けていると、SVN コマンドの入力がめんどうになってくる場面があります。
今日は、SVN コマンドの入力を簡略化するために、僕が作成したシェルスクリプトをいくつか紹介します。

1) プログラムのリビジョンを一つ前に戻す
誤ってプログラムしたり、プログラムを変更してコミットしたあと、一つ前のバージョンに戻したい場合がたまにあります。そんなときは、SVN コマンドの場合は、次のように入力します。

svn merge -r 上書き対象のリビジョン番号:戻すリビジョン番号 対象のファイル名


このコマンドを使うには、対象ファイルのリビジョン番号を svn info で調べないとリビジョンを指定することができないので、次のようなスクリプトを作ってみました。

#!/bin/sh

if [ $# == 0 ]; then
  echo "Usage:" svn_revert [svn target file name]
  exit -1
fi

if [ ! -e $1 ]; then
  echo "Could not found file. -" $1
  exit -1
fi

SVN=/usr/local/bin/svn
grep_rev='grep Revision:'

export LANG=
revision=`$SVN info $1 | $grep_rev | awk '{printf "%s\n", $2}'`
prev_revision=`expr $revision - 1`

$SVN merge -r $revision:$prev_revision $1

echo "svn reverted '$prev_revision' done."


やっていることは、とても単純で対象のファイルのリビジョンを調べて、その一つ前のリビジョン番号のファイルにしています。(そのままですね。。。)
このシェルスクリプトは、見て分かるとおり grep, awk, expr が必要です。どうして、awk を使ったのかというと、深い理由はあまりありませんが awk で遊んでみたかっただけです。なお、リビジョン番号が 1 だったときなどのエラー処理はしていませんので、注意して使ってください。
このシェルスクリプトは引数にリビジョンを一つ戻したいファイル名をします。実行した後は、コミットすれば一つ前のリビジョンにファイルを戻すことができます。しかも、元に戻したリビジョンが表示されるので、コミットログに分かりやすく残すことができます。


2) トランクの変更をブランチにマージする
僕が今担当しているプロジェクトでは、トランクとブランチに別れて開発しています。僕はおもにブランチの開発を担当していますが、並行で行われているトランクの変更をブランチ側にマージしなければいけません。
僕は初めて SVN でブランチで開発していたので、トランク側での変更をブランチ側にマージするときに何度もミスをしてしまったのですが、やっと正しいマージの方法を理解したので忘れないように、次のようなシェルスクリプトを書いてみました。

#!/bin/sh

if [ $# == 0 ]; then
  echo "Usage:" svn_merge [trunk head revision]
  exit -1
fi

cd ~/SVNリポジトリの場所
SVN=/usr/local/bin/svn
$SVN merge -r ブランチをしたときのトランクのリビジョン番号:$1 マージ元のトランクのURL


これは、シェルスクリプトで書くまでもなくコマンドのエイリアスでも十分だと思いますが、シェルに依存しないようにシェルスクリプトにしてみました。このシェルスクリプトのポイントは、ブランチをしたときのトランクのリビジョン番号を設定することです。
インターネットで調べてみると、ブランチの変更をトランクへマージする SVN コマンドの使い方はよく書かれていますが、その逆のトランクの変更をブランチにマージする SVN コマンドの使い方があまり情報がなくて、苦労しました。


あとは、トランクとブランチの両方を変更する場面に直面したときに、トランクとブランチを切り替えられるシェルスクリプトを作ってみたり、トランクとブランチの差分をとるシェルスクリプトを作ってみました。これは、SVN コマンド一つでできますが、SVN リポジトリの URL が長いので、シェルスクリプトにすると便利です。

まだこれだけのスクリプトだと不十分で、次のようなことを改善できる方法があればぜひ教えてください。
・衝突してしまったファイルを手動で一通り修正した後、svn resolved で衝突を改善するときにまだ修正もれがあれば通知してくれるプログラム
・コミットする前に、デバッグコード(たとえば、コメントに // DEBUG や // FIXME と入っているコードがコミットできないようする commit フックプログラム(たしか、CSV では衝突したプログラムはコミットできないようになっていたと思いますが、svn では設定によるのでしょうか?)


業務が忙しくなればなるほどこういう小さな改善が効果をもたらしてくれると思うので、時間が作りながら日々の業務の効率を上げていきたいと思います。