回答:
可能であれば、最初にすべての.svn
フォルダーを削除することもできます。欠点:誰かがSVNを使用している場合、バージョン管理情報が失われます。誰かがSVNを使用している場合、それらのフォルダーを削除することはお勧めできません(またはSVNはフォルダーとファイルを追跡しているため、実際にはSVNからも削除する必要があります)。
それが不可能な場合は、スクリプトルートを使用します。
for folder in $(find . -type d); do
if [ "`ls $folder | wc -l`" -eq 0 ]; then
echo "I am going to delete $folder"
fi
done
驚くべきことがあるかもしれないので、最初に試運転を試してください。その後rm -r
、その代わりに変更できますecho
。
ただし、これにより、ドットファイルのみを持つすべてのフォルダーa/.this_is_super_important
が削除されます(他のファイルやフォルダーがない場合は、たとえば削除されます)。
小さな変更(ディレクトリを単に印刷し、xargs
後でパイプする):
for folder in $(find -type d ! -path *.svn*); do
if [ "`find $folder ! -path *.svn* ! -path $folder | wc -l`" -eq 0 ]; then
echo $folder
fi
done
これをあなたののどこかに入れて$PATH
、おそらくsvn-empties
最初に実行してください:
svn-empties
見つかったディレクトリをリストし(必要に応じてリストを変更し)、次にパイプしxargs
ます:
svn-empties | xargs svn rm
このスクリプトは、使用中に非常に役立ちましたgit-svn
(ありがとう!)。git
空のディレクトリを追跡しないため、Subversionリポジトリに多くの空のディレクトリができてしまいます。私はsvn co
、リポジトリの別のコピーと実行しsvn-empties | xargs svn rm
、定期的に。そもそもSubversionを使用することは私の決定ではありませんでした;)
git-svn
、あなたが使用することをお勧めします--rmdir
のオプションをgit svn dcommit
。ディレクトリが空になるとすぐに、svnからディレクトリを削除します。
私はこれにつまずいたので、このスクリプトを使用しましたが、.svnを持ち、隠しファイルまたは通常のファイル以外の空のディレクトリのみを適切に考慮するように修正しました。
また、私はsvn rmを使用しているため、これはリポジトリに対して機能することを前提としているため、ディレクトリ上で別のことを行うようにスクリプトを適合させることができます。
for folder in $(find -type d ! -path *.svn*); do
if [ "`find $folder ! -path *.svn* ! -path $folder | wc -l`" -eq 0 ]; then
svn rm $folder
fi
done
空白find
やIFS
マジックの問題を回避するために(ファイル名には実際に改行も含めることができるためIFS=$'\n'
、特効薬ではありません)、globと配列を使用できます。
#!/bin/bash
search_dir=${1:-.}
shopt -s globstar dotglob
for svn_dir in "$search_dir"/**/.svn/; do
base_dir=${svn_dir%/.svn/}
base_dir_contents=("$base_dir"/*)
if [ ${#base_dir_contents[@]} -eq 1 ]; then
printf 'The directory "%s" only contains ".svn/".\n' "$base_dir"
fi
done
globstar
ディレクトリトラバース**
コンストラクトを有効にします。dotglob
アスタリスクグロブに隠しファイルが含まれます。for
グロブは、任意の問題のディレクトリ名の文字に対して安全でなければなりません。グロブがします常にの場合ではありませんこれは、バッシュで安全に拡張しls
、find
最後のスラッシュは、我々は唯一の一致を確認します、などのフォルダの名前.svn
ではなく、通常のファイル(ただし、実際のコーナーケースを、)。.svn
ディレクトリを持つフォルダーに含まれるファイルの名前は、配列にまとめられます。この配列内のアイテムの数が1(つまり、.svn
構造上*が知っているフォルダ)が存在する場合、それが探しているものです。Bashビルトインのみを使用するためfind
、に余分なシステムフォークを発行するよりも高速である必要がありますが、違いはほとんど目立たず、I / Oが主なボトルネックになります。
*:マイナー追記(だけでなく他のソリューションに適用されます):そこ例のみがあれば潜在的な競合状態がある.svn
とfoo
、ディレクトリ内のファイル、および.svn
ディレクトリが削除される間for
とにつながる配列グロブfoo
削除されます同様に。ただし、悪意のある人がファイルシステム内のファイルを削除する権限を持っている場合、ゲームはすでに失われている可能性があり、タイミング攻撃よりも簡単に直接削除できます。
別の簡単な言及は、他の答えは*.svn*
拡張を引用する必要があるということです。それ以外のfind
場合、現在のフォルダーにそのグロブに一致するファイルが含まれていると、コマンドは失敗します。
$ mkdir foo && cd foo
$ mkdir -p test1/.svn test2
$ find -type d ! -path *.svn*
.
./test1
./test2
$ touch foo.svnbar
$ find -type d ! -path *.svn*
.
./test1
./test1/.svn
./test2
$ find -type d ! -path "*.svn*"
.
./test1
./test2
引用符*.svn*
がないと、シェルによってに早まって展開されfoo.svnbar
ます。
svn-empties YOU_WANT_TO_SEARCH_PATH
C_IFS=$IFS
IFS=$'\n'
for folder in $(find "$1" -depth -type d ! -path *.svn*|sort -r); do
counts=$(find "$folder" -type f ! -path *.svn* ! -path $folder | wc -l)
if [ $counts -eq 0 ]; then
echo $folder
fi
done
IFS=$C_IFS
.svn
ディレクトリが空の?