2015年6月23日火曜日

[subversion] 特定ディレクトリ以下をサーバーとの同期対象から除外する方法

subversionでチェックアウトした作業コピー内の特定ディレクトリ以下をサーバーとの同期対象から除外したい、ということを考えたことはないでしょうか。
例えば、リポジトリの特定ディレクトリ以下に自分にとって不要なファイルやアーカイブが多数コミットされていると、以下のような無駄が生じます。これらの無駄をなくしたい、というのが主なユースケースです。
  • 不要なファイル・アーカイブによってディスクスペースが占有される
  • サーバー上に更新が発生した際にupdateに余計な時間がかかってしまう

単純に特定ディレクトリ以下の作業ファイルを削除してしまうと、コミット時に差分として検知されてしまう、また、次回以降のupdateコマンドで再ダウンロードされてしまう、という非常に残念な挙動になります。
このようなケースでは以下の方法を使えば、差分が検知されない状態で所定ディレクトリ以下のファイルを削除し、かつ、差分として検知されることも、リポジトリの更新に伴って再度ダウンロードされることもない状態をキープできます。

特定ディレクトリ以下のファイル・ディレクトリを削除する:

--set-depthオプションで対象ディレクトリのDepthを"empty"に設定します。
具体的には、以下のコマンドを実行します。
% svn --set-depth empty update TARGET-DIR
TortoiseSVNを利用している場合には、ディレクトリを選択した状態で右クリックし、[TortoiseSVN] → [特定のリビジョンへ更新] → [更新の深さ]で"empty"を指定します。

特定ディレクトリ以下のファイル・ディレクトリを再度取得する:

--set-depthオプションで対象ディレクトリのDepthを"infinity"に設定します。
具体的には、以下のコマンドを実行します。
% svn --set-depth infinity update TARGET-DIR
TortoiseSVNを利用している場合には、ディレクトリを選択した状態で右クリックし、[TortoiseSVN] → [特定のリビジョンへ更新] → [更新の深さ]で"infinity"を指定します。

特定ディレクトリのDepthを確認する方法:

ディレクトリを指定してinfoコマンドを実行すると、Depth項目として以下のいずれかが表示されます。
  • empty
  • files
  • immediates
  • infinity
  • exclude
TortoiseSVNを利用している場合には、ディレクトリを選択した状態で右クリックし[プロパティ]で表示されるダイアログの[Subversion]タブを表示すると、その中にDepth項目があります。

emptyとexcludeの違い:

Sparse Directories (nightly)の情報によると、--set-depth emptyと--set-depty excludeはにた効果が得られますが、以下の点が異なります。ディスク消費を減らす目的があるのであればemptyが正解です。infinityと頻繁に切り替えるのであればexcludeを利用するのが良いと思われます。
  • empty
    • チェックアウト済みのファイル・サブディレクトリは再帰的に全て削除される
  • exclude
    • チェックアウト済みのファイル・サブディレクトリは全てリポジトリ管理外のファイルとしてそのまま残る
    • 1.6以降で新しくサポートされたオプション

参考: