Subversionのバージョン管理外ファイルを自動的に削除する


111

バージョン管理されていない作業コピー内のすべてのファイルを再帰的に削除する方法を誰かが知っていますか?(自動ビルドVMwareでより信頼性の高い結果を得るには、これが必要です。)


7
私はSVNユーザーで、GitをSVNと比較して、最終的に切り替えたいかどうかを確認しています。これは、Gitが「git clean」コマンドを使用して輝く別の例のようです。
jpierson

3
またはhg purge --allMercurialで。
ブレンダンロング

stackoverflow.com/questions/2803823/の複製で、より多くの便利なアクティビティがあります。
ヒースラフタリー2018

回答:


26

編集:

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))

それはかなりうまくやっているようです。


1
Python 2.7.2でも動作します。Warren P:詳細を提供できますか?
Thomas Watnedal 2014年

Python 2.6の問題だと思います。2.7で再び動作します。
ウォーレンP

1
反対票:怒鳴るからの他の解決策svn cleanup --remove-unversionedはより良いです。そしてそれはSubversion 1.9.0用です(このバージョンは2015年のものです)。安定していて標準です。
tres.14159

138

これは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コマンドを使用できます


6
Windowsのcygwinでも使用できます。
ホンザ

9
スペースを含むファイル名の場合は-dオプションをxargsに追加し、追加されたディレクトリの場合は-rオプションをrmに追加することを検討してください。grep ^ \?| カット-c9- | xargs -d \\ n rm -r
Seth Reno

4
OS Xで実行されている-dオプションにも問題がありました。私の代替案は次のとおりです。これは改行をnull文字に変換し、xargsの-0オプションを使用してファイル名のスペースを処理します。grep ^ \?| カット-c9- | tr '\ n' '\ 0' | xargs -0 rm
ブライアンウェブスター

3
別のコマンドの出力の正確な文字数に依存するコマンドをsvn status | grep "^?" | awk '{print $2}' | xargs -d \\n rm -r
嫌がる場合

3
@Pavel xargs --no-run-if-emptyオプションをご覧ください
Ken

71

自動化されたビルドではないが、同じことをしようとしてこのページに出くわした。

もう少し調べた後、TortoiseSVNで「拡張コンテキストメニュー」を発見しました。Shiftキーを押しながら作業コピーを右クリックします。TortoiseSVNメニューの下に追加のオプションがあります。バージョン管理されていないアイテムを削除...」。

この特定の質問(つまり、自動化されたビルドのコンテキスト内)にはおそらく適用されないかもしれませんが、同じことを実行しようとしている他のユーザーに役立つと思いました。


すごい!XPでは、リストビュー(エクスプローラーの右側)でのみ機能し、ツリービュー(左側)では機能しません。
Christopher Oezbek

幻想的で、それをごみ箱に送るだけで、そのまま削除するのがいいでしょう。ちょうど私が必要としたもの。
Dean Thomas

TortoiseSVNのTortoiseProc.exeを使用して、コマンドラインでこれを自動化することもできます。詳細は以下の私の回答にあります。
stevek_mcc 2016


9

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"

1
このちょっと私のために働いた。いくつかのバージョン管理されていないフォルダーを窒息させるように見えた。
jpierson

7

これをWindows PowerShellプロファイルに追加しました

function svnclean {
    svn status | foreach { if($_.StartsWith("?")) { Remove-Item $_.substring(8) -Verbose } }
}

2
@FelipeAlvarezはい。はい、そうです。それはスライスされたパン以来の最高のものではありませんが、それはバッチに勝ります。.NETアセンブリをプルインできるので、少なくともbashと同じくらい便利だと思います。
jpmc26 14年

Microsoftの冗長性への嫌悪傾向(コマンド名の長さだけでなく、インターネットから巨大なスニペットをコピーしないと何もできない)に悩まされていますが、驚くほど便利で、かなりよく考え抜かれています。
Warren P

1
あなたは追加することができます--no-ignoresvn statusして-RecurseRemove-Item
ケヴィン・スミス

5

Linuxコマンドライン:

svn status --no-ignore | egrep '^[?I]' | cut -c9- | xargs -d \\n rm -r

または、ファイルの一部がルートによって所有されている場合:

svn status --no-ignore | egrep '^[?I]' | cut -c9- | sudo xargs -d \\n rm -r

これはケンの答えに基づいています。(ケンの答えは無視されたファイルをスキップします。私の答えはそれらを削除します)


5

unix-shellで次のように実行するだけです。

rm -rf `svn st . | grep "^?" | cut -f2-9 -d' '`

削除するファイルの数がコマンドライン引数の最大数を超える場合、これは機能しません。xargsベースの回答も参照してください。
maxschlepzig 2014

4

新しい場所にエクスポートして、そこからビルドすることはできませんか?


1
自動ビルドの場合は、クリーンなエクスポートが必要です。
g。

1
理想的にはこれを行いますが、チェックアウトが非常に大きい場合は問題があります。これが、OPがビルドを短くするように求めた理由である可能性があります。
jpmc26 14年

4

あなたは持っている場合はTortoiseSVNのをあなたのパスに、あなたは右のディレクトリにあります。

TortoiseProc.exe /command:cleanup /path:"%CD%" /delunversioned /delignored /nodlg /noui

オプションはTortoiseSVNヘルプで説明されています/command:cleanup

/ nouiを使用して、結果ダイアログがポップアップ表示され、クリーンアップが終了したことを通知したり、エラーメッセージを表示したりしないようにします。/ noprogressuiは、進行状況ダイアログも無効にします。/ nodlgは、ユーザーがクリーンアップで実行する必要があることを正確に選択できるクリーンアップダイアログの表示を無効にします。使用可能なアクションは、ステータスのクリーンアップ、/ revert、/ delunversioned、/ delignored、/ refreshshell、/ externalsのオプション/ cleanupで指定できます。


4

亀のsvnを使用している場合、これを行うための隠しコマンドがあります。Windowsエクスプローラーでコンテキストメニューを起動するには、Shiftキーを押しながらフォルダーを右クリックします。「バージョン管理外アイテムの削除」コマンドが表示されます。

詳細については、このページの下部を参照してください。または、以下のスクリーンショットで、緑色の星で拡張機能を強調表示し、黄色の長方形で対象の機能を強調表示しています...

SVN拡張コンテキストメニューと標準メニュー



3

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();
    }
}

バージョン管理されていないファイルは後で移動する必要がある場合に備えて、移動したいのですが。
leppie 2008年

もちろん開発マシンでは-しかし、VMwareのビルドでは、誰もそれにログオンしてファイルを作成することができません。
Stefan Schultze、

おかげで、私はこれをcruisecontrolのMSBuildスクリプトの一部として使用して、ビルドの前にソースディレクトリをクリーンアップしました-gregmac
11/27

あなたのコードに基づいて始まり、さらに進んだ:github.com/tgmayfield/svn-clean-sharp/downloads
Tom Mayfield

3
svn st --no-ignore  | grep '^[?I]' | sed 's/^[?I]  *//' | xargs -r -d '\n' rm -r

これは、Subversionの管理下にないすべてのファイルを削除するUNIXシェルコマンドです。

ノート:

  • st中には、svn stビルドでの別名であるstatus、すなわちコマンドは同等ですsvn status
  • --no-ignoreステータス出力に非リポジトリファイルも含まれます。それ以外の場合は、.cvsignoreなどのメカニズムを介して無視されます。ビルドの開始点を明確にすることが目標であるため、このスイッチは必須です。
  • grep転覆に、このような出力が唯一の未知のファイルフィルタが残っている-行が始まる?せずに無視されるだろう転覆にリストファイルの不明な--no-ignoreオプション
  • ファイル名までの接頭辞は、 sed
  • xargsコマンドを介して、指示され-r実行されないためにrm引数リストが空になるとき、
  • この-d '\n'オプションはxargs、改行を区切り文字として使用するように指示します。このようなコマンドは、スペースを含むファイル名に対しても機能します
  • rm -r (リポジトリの一部ではない)完全なディレクトリを削除する必要がある場合に使用されます

2

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 &quot;${basedir}&quot;" 
                       outputProperty="status" />
    <echo message="Deleting any unversioned files:" />
    <for list="${status}" param="p" delimiter="&#x0a;" 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}参照を変更します。


1
注:バージョン管理されていないファイルのみを削除します。バージョン管理されていない空のフォルダは削除されません。

2
svn status --no-ignore | awk '/^[I\?]/ {system("echo rm -r " $2)}'

それがあなたがしたいことが確かであるならば、エコーを取り除いてください。


1
これは、nが削除されるファイルに対してn個/bin/shとn個のrmプロセスがfork されるため、xargsベースの回答よりも劣ります。
maxschlepzig 2014

同意した。xargs情報をありがとう。
アリア


1

別のオプションも提供する可能性があります

svn status | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'

/(config|.ini)/は私自身の目的のためです。

そして、svnコマンドに--no-ignoreを追加することをお勧めします



1

純粋なWindows cmd / batソリューション:

@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

実際、このスクリプトは私のファイルを削除しませんでした。おそらくスペースが原因です。@SukeshNambiarによる1行の回答でうまくいきました。
Christiaan Westerbeek 2014

1

私はこの回答からセス・リノのバージョンを試しましたが、それは私にとってはうまくいきませんでした。ファイル名の前に8文字あり、9文字ではありませんcut -c9-いる。

だからこれはsed代わりに私のバージョンですcut

svn status | grep ^\? | sed -e 's/\?\s*//g' | xargs -d \\n rm -r

1

あなたがpowershellでクールなら:

svn status --no-ignore | ?{$_.SubString(0,1).Equals("?")} | foreach { remove-item -Path (join-Path .\ $_.Replace("?","").Trim()) -WhatIf }

-WhatIfフラグを削除して、コマンドが実際に削除を実行するようにします。それ以外の場合は、単に出力それがどうなるかを考え実行している場合は-WhatIfなしで行います。


1

これをトーマス・ワトネダルの回答へのコメントとして追加します、まだできません。

(Windowsには影響しません)の小さな問題は、ファイルまたはディレクトリのみをチェックすることです。シンボリックリンクが存在する可能性があるUnixのようなシステムの場合、行を変更する必要があります。

if os.path.isfile(fullpath):

if os.path.isfile(fullpath) or os.path.islink(fullpath):

リンクも削除します。

私にとって、最後の行if match: removeall(match.group(1))

    if match:
        print "Removing " + match.group(1)
        removeall(match.group(1))

削除するものを表示するのも便利でした。

ユースケースによっては、?[\?ID]正規表現の一部は、より良いようなものであってもよい?[\?I]よう、Dまた削除しバージョン管理下にあったファイルを、削除しました。これを使用してクリーンでチェックインされたフォルダーをビルドしたいので、D状態にファイルはありません。


1

@zhoufei私はあなたの答えをテストしました、そしてここに更新されたバージョンがあります:

FOR /F "tokens=1* delims= " %%G IN ('svn st %~1 ^| findstr "^?"') DO del /s /f /q "%%H"
FOR /F "tokens=1* delims= " %%G IN ('svn st %~1 ^| findstr "^?"') DO rd /s /q "%%H"
  • %GとHの前に2つのマークを使用する必要があります
  • 順序を切り替えます。最初にすべてのファイルを削除してから、すべてのディレクトリを削除します
  • (オプション:) %~1任意のディレクトリ名を使用できる代わりに、これをbatファイルの関数として使用したので%~1、最初の入力パラメーター

0

コードを記述したくない場合は、svn2svnのsvn2.exeがこれを行います。また、記事もあります。の実装方法ます。削除されたフォルダとファイルはごみ箱に入れられます。

「svn2.exe sync [path]」を実行します。


0

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();


0

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 ()

0

これを生成するのに約3時間を使用しました。Unixで実行するには5分かかります。主な問題は、Winフォルダーの名前にスペースが含まれていること、%% iを編集できないこと、Win cmdループで変数を定義するときに問題が発生することでした。

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!
)

0

上記のC#コードスニペットが機能しませんでした-亀の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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.