バージョン管理されていない作業コピー内のすべてのファイルを再帰的に削除する方法を知っている人はいますか? (これは、VMware の自動ビルドでより信頼性の高い結果を得るために必要です。)
32 に答える
これはbashで機能します:
svn status | egrep '^\?' | cut -c8- | xargs rm
Seth Renoの方が優れています:
svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r
ファイル名のバージョン管理されていないフォルダーとスペースを処理します
以下のコメントによると、これは Subversion が認識していないファイル (status=?) でのみ機能します。Subversionが認識しているもの (無視されたファイル/フォルダーを含む) は削除されません。
Subversion 1.9 以降を使用している場合は、 --remove-unversioned および --remove-ignored オプションを指定してsvn cleanupコマンドを使用するだけです。
自動ビルドではありませんが、同じことをしようとしているときに、このページに出くわしました。
もう少し調べてみると、TortoiseSVNの「拡張コンテキスト メニュー」が見つかりました。Shift キーを押しながら作業コピーを右クリックします。TortoiseSVN メニューの下に、「バージョン管理されていないアイテムを削除...」などの追加オプションが追加されました。
この特定の質問 (つまり、自動ビルドのコンテキスト内) には当てはまらないかもしれませんが、同じことをしようとしている他の人にとっては役立つかもしれないと思いました。
編集:
Subversion 1.9.0 では、これを行うオプションが導入されました。
svn cleanup --remove-unversioned
その前に、この python スクリプトを使用してそれを行います。
import os
import re
def removeall(path):
if not os.path.isdir(path):
os.remove(path)
return
files=os.listdir(path)
for x in files:
fullpath=os.path.join(path, x)
if os.path.isfile(fullpath):
os.remove(fullpath)
elif os.path.isdir(fullpath):
removeall(fullpath)
os.rmdir(path)
unversionedRex = re.compile('^ ?[\?ID] *[1-9 ]*[a-zA-Z]* +(.*)')
for l in os.popen('svn status --no-ignore -v').readlines():
match = unversionedRex.match(l)
if match: removeall(match.group(1))
それはかなりうまく機能しているようです。
参照: svn-clean
Windows コマンド ラインを使用している場合は、
for /f "tokens=2*" %i in ('svn status ^| find "?"') do del %i
改良版:
for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%i %j"
これをバッチ ファイルで使用する場合は、以下を 2 倍にする必要があります%
。
for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%%i %%j"
これを Windows PowerShell プロファイルに追加しました
function svnclean {
svn status | foreach { if($_.StartsWith("?")) { Remove-Item $_.substring(8) -Verbose } }
}
Linux コマンドライン:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | xargs -d \\n rm -r
または、一部のファイルが root によって所有されている場合:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | sudo xargs -d \\n rm -r
これはケンの答えに基づいています。(ケンの回答は無視されたファイルをスキップします;私の回答はそれらを削除します)。
Tortoise svnを使用している場合、これを行うための隠しコマンドがあります。Shiftキーを押しながらフォルダを右クリックして、Windowsエクスプローラのコンテキストメニューを起動します。「バージョン管理されていないアイテムの削除」コマンドが表示されます。
詳細については、このページの下部を参照してください。または、下のスクリーンショットで、緑色の星で拡張機能を強調表示し、黄色の長方形で関心のある機能を強調表示しています...
パスにTortoiseSVNがあり、正しいディレクトリにいる場合:
TortoiseProc.exe /command:cleanup /path:"%CD%" /delunversioned /delignored /nodlg /noui
オプションについては、TortoiseSVN ヘルプで/command:cleanup
次のように説明されています。
/noui を使用して、クリーンアップが終了したことを通知したり、エラー メッセージを表示したりする結果ダイアログが表示されないようにします)。/noprogressui は進行状況ダイアログも無効にします。/nodlg は、ユーザーがクリーンアップで何を行うべきかを正確に選択できるクリーンアップ ダイアログの表示を無効にします。使用可能なアクションは、ステータス クリーンアップのオプション /cleanup、/revert、/deunversioned、/deignored、/refreshshell、および /externals で指定できます。
新しい場所にエクスポートしてそこからビルドすることはできませんか?
Thomas Watnedals Python スクリプトの私の C# 変換:
Console.WriteLine("SVN cleaning directory {0}", directory);
Directory.SetCurrentDirectory(directory);
var psi = new ProcessStartInfo("svn.exe", "status --non-interactive");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.WorkingDirectory = directory;
using (var process = Process.Start(psi))
{
string line = process.StandardOutput.ReadLine();
while (line != null)
{
if (line.Length > 7)
{
if (line[0] == '?')
{
string relativePath = line.Substring(7);
Console.WriteLine(relativePath);
string path = Path.Combine(directory, relativePath);
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
else if (File.Exists(path))
{
File.Delete(path);
}
}
}
line = process.StandardOutput.ReadLine();
}
}
svn st --no-ignore | grep '^[?I]' | sed 's/^[?I] *//' | xargs -r -d '\n' rm -r
これは、Subversion の制御下にないすべてのファイルを削除する UNIX シェル コマンドです。
ノート:
st
inはのsvn st
組み込みエイリアスですstatus
。つまり、コマンドはsvn status
--no-ignore
ステータス出力にリポジトリ以外のファイルも含めます。それ以外の場合は、.cvsignore
などのメカニズムを介して無視します。-目標はビルドの開始点をクリーンにすることであるため、このスイッチは必須です- subversion にとって不明なファイルのみが残されるように出力をフィルター処理します -オプションなしでは無視される、subversion にとって不明なファイル
grep
のリストで始まる行?
--no-ignore
- ファイル名までのプレフィックスは次の方法で削除されます
sed
- 引数リストが空になる場合、コマンドは実行しないように
xargs
指示されます-r
rm
- この
-d '\n'
オプションはxargs
、改行を区切り文字として使用するように指示するため、コマンドはスペースを含むファイル名でも機能します rm -r
完全なディレクトリ (リポジトリの一部ではない) を削除する必要がある場合に使用されます
上記のいずれも、win32 の自動ビルド システムに追加する必要のない追加の依存関係がなければ動作しませんでした。そこで、次の Ant コマンドをまとめました。これらには、Ant-contrib JAR をインストールする必要があることに注意してください (Ant 1.7.0 で最新のバージョン 1.0b3 を使用していました)。
これにより、バージョン管理されていないすべてのファイルが警告なしに削除されることに注意してください。
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<taskdef name="for" classname="net.sf.antcontrib.logic.ForTask" />
<macrodef name="svnExecToProperty">
<attribute name="params" />
<attribute name="outputProperty" />
<sequential>
<echo message="Executing Subversion command:" />
<echo message=" svn @{params}" />
<exec executable="cmd.exe" failonerror="true"
outputproperty="@{outputProperty}">
<arg line="/c svn @{params}" />
</exec>
</sequential>
</macrodef>
<!-- Deletes all unversioned files without warning from the
basedir and all subfolders -->
<target name="!deleteAllUnversionedFiles">
<svnExecToProperty params="status "${basedir}""
outputProperty="status" />
<echo message="Deleting any unversioned files:" />
<for list="${status}" param="p" delimiter="
" trim="true">
<sequential>
<if>
<matches pattern="\?\s+.*" string="@{p}" />
<then>
<propertyregex property="f" override="true" input="@{p}"
regexp="\?\s+(.*)" select="\1" />
<delete file="${f}" failonerror="true" />
</then>
</if>
</sequential>
</for>
<echo message="Done." />
</target>
別のフォルダーの場合は、${basedir}
参照を変更します。
svn status --no-ignore | awk '/^[I\?]/ {system("echo rm -r " $2)}'
やりたいことが確かな場合は、エコーを削除してください。
別のオプションに貢献するかもしれません
svn status | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'
/(config|.ini)/は私自身の目的のためのものです。
そして、svnコマンドに--no-ignoreを追加するのは良い考えかもしれません
あなたがpowershellに慣れているなら:
svn status --no-ignore | ?{$_.SubString(0,1).Equals("?")} | foreach { remove-item -Path (join-Path .\ $_.Replace("?","").Trim()) -WhatIf }
-WhatIf フラグを削除して、コマンドが実際に削除を実行するようにします。それ以外の場合は、-WhatIf なしで実行した場合にどうなるかを出力するだけです。
この回答からSeth Reno のバージョンを試しましたが、うまくいきませんでした。ファイル名の前に 8 文字がありました。cut -c9-
だから、これはsed
代わりに私のバージョンですcut
:
svn status | grep ^\? | sed -e 's/\?\s*//g' | xargs -d \\n rm -r
純粋な Windows コマンド/バット ソリューション:
@echo off
svn cleanup .
svn revert -R .
For /f "tokens=1,2" %%A in ('svn status --no-ignore') Do (
If [%%A]==[?] ( Call :UniDelete %%B
) Else If [%%A]==[I] Call :UniDelete %%B
)
svn update .
goto :eof
:UniDelete delete file/dir
if "%1"=="%~nx0" goto :eof
IF EXIST "%1\*" (
RD /S /Q "%1"
) Else (
If EXIST "%1" DEL /S /F /Q "%1"
)
goto :eof
RH5 マシンで svn-clean を見つけました。/usr/bin/svn-clean にあります
http://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svn-clean
python、Unix shell、java などの代わりに perl でこれを行うのが好きな人のために、jib も行う小さな perl スクリプトをここに示します。
注: これにより、バージョン管理されていないすべてのディレクトリも削除されます
#!perl
use strict;
sub main()
{
my @unversioned_list = `svn status`;
foreach my $line (@unversioned_list)
{
chomp($line);
#print "STAT: $line\n";
if ($line =~/^\?\s*(.*)$/)
{
#print "Must remove $1\n";
unlink($1);
rmdir($1);
}
}
}
main();
PERL でこれを行うクリーンな方法は次のとおりです。
#!/usr/bin/perl
use IO::CaptureOutput 'capture_exec'
my $command = sprintf ("svn status --no-ignore | grep '^?' | sed -n 's/^\?//p'");
my ( $stdout, $stderr, $success, $exit_code ) = capture_exec ( $command );
my @listOfFiles = split ( ' ', $stdout );
foreach my $file ( @listOfFiles )
{ # foreach ()
$command = sprintf ("rm -rf %s", $file);
( $stdout, $stderr, $success, $exit_code ) = capture_exec ( $command );
} # foreach ()
これを生成するのに約 3 時間かかりました。Unix でこれを行うには 5 分かかります。主な問題は、Win フォルダーの名前にスペースが含まれていること、%%i を編集できないこと、および Win コマンド ループで変数を定義することに関する問題でした。
setlocal enabledelayedexpansion
for /f "skip=1 tokens=2* delims==" %%i in ('svn status --no-ignore --xml ^| findstr /r "path"') do (
@set j=%%i
@rd /s /q !j:~0,-1!
)
次のものも見つけて使用しました:svn status --no-ignore| awk '/^?/ {print $2}'| xargs rm
上記の C# コード スニペットは機能しませんでした。tortoise svn クライアントを使用しており、行の形式が少し異なります。これは上記と同じコード スニペットですが、機能するように書き直され、正規表現を使用しています。
/// <summary>
/// Cleans up svn folder by removing non committed files and folders.
/// </summary>
void CleanSvnFolder( string folder )
{
Directory.SetCurrentDirectory(folder);
var psi = new ProcessStartInfo("svn.exe", "status --non-interactive");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.WorkingDirectory = folder;
psi.CreateNoWindow = true;
using (var process = Process.Start(psi))
{
string line = process.StandardOutput.ReadLine();
while (line != null)
{
var m = Regex.Match(line, "\\? +(.*)");
if( m.Groups.Count >= 2 )
{
string relativePath = m.Groups[1].ToString();
string path = Path.Combine(folder, relativePath);
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
else if (File.Exists(path))
{
File.Delete(path);
}
}
line = process.StandardOutput.ReadLine();
}
}
} //CleanSvnFolder