Subversionでtagsを守る

Subversionにおいて、tags/に置いたタグに対して、初回commit以外更新させないためにはフックを使用する。しかし、具体的な記述は軽くググってもすんなり出てこなかったので記事にしておく。

タグ

Subversionのタグはただのtrunkのコピーなので、そのままだと更新ができてしまう。

subversionでのリポジトリの基本構成(タグに関係するところだけ)

trunk/
tags/

tagAを登録

svn co $REPO/ trunk
~ 何らかの更新のコミット
// tagAを登録
svn copy trunk tags/tagA
svn commit $REPO/tags/tagA -m "Register tagA" 

tagAを得たいとき

svn co $REPO/tags/tagA

tags/が特別守られているわけではないので、誤ってtagA以下を更新することがあり得る

svn co $REPO/tags/tagA
cd tagA
touch file1
svn add file1
svn commit -m "Miss"
// できてしまう

フック

$REPO/hooks/pre-commitを作成し、実行権限を持たせる。
コミット前にpre-commitが実行され、pre-commitが0以外を返した場合、コミットが中止される。
pre-commitには引数としてリポジトリとトランザクションが与えられ、svnlookコマンドを使うとコミットしようとするファイル名やファイル内容が解析できるので、それを元にコミット可否を決められる。

まずはすべてのtags/へのコミットを禁止するpre-commitが以下。importも防いでくれる。

#!/bin/sh

# 対象リポジトリ
REPOS="$1"
# トランザクション番号
TXN="$2"

# svnlookのパス
SVNLOOK="/usr/bin/svnlook"

# トランザクション番号とリポジトリ名を使ってコミット対象のリストを取得するためのコマンド
CHANGED_CMD="$SVNLOOK changed -t $TXN $REPOS"

for line in `$CHANGED_CMD`
do

  # tags/へのコミットは基本エラー
  if echo "$line" | grep -E '^tags' ; then
    echo "Error: don't change tags/" >&2
    exit 1
  fi
done

exit 0

ただ、これだと初回の登録もできない。
タグを登録するときだけ、登録したいタグを指定して一時的に許可するようにしたpre-commitが以下。タグを打つのは管理者であろうから

#!/bin/sh

# 登録したいtag。空文字で一切無許可
TAG="tagA"

# 対象リポジトリ
REPOS="$1"
# トランザクション番号
TXN="$2"

# svnlookのパス
SVNLOOK="/usr/bin/svnlook"

# トランザクション番号とリポジトリ名を使ってコミット対象のリストを取得するためのコマンド
CHANGED_CMD="$SVNLOOK changed -t $TXN $REPOS"

for line in `$CHANGED_CMD`
do

  # echo "Check line:$line" >&2
  # tags/へのコミットは基本エラー($TAGだけ例外)
  if echo "$line" | grep -E '^tags' ; then
    if [ -n "$TAG" ]; then
      # echo "Check whether file is tags/$TAG" >&2
      if echo "$line" | grep -E "^tags/$TAG/" ; then
        # echo "Ignore tags/$TAG" >&2
        continue
      fi
    fi
    echo "Error: Don't change tags/" >&2
    exit 1
  fi
done

exit 0

というわけであまりスマートではない気がするのだけどとりあえずはできそう。

この記事が気に入ったらサポートをしてみませんか?