webentwicklung-frage-antwort-db.com.de

Unversionierte Dateien von Subversion automatisch entfernen

Kennt jemand eine Möglichkeit, alle Dateien in einer Arbeitskopie, die nicht der Versionskontrolle unterliegen, rekursiv zu entfernen? (Ich brauche dies, um zuverlässigere Ergebnisse bei meiner automatischen VMware-Erstellung zu erzielen.)

108
Stefan Schultze

Bearbeiten:

Subversion 1.9.0 hat dazu eine Option eingeführt:

svn cleanup --remove-unversioned

Zuvor benutze ich dieses Python-Skript dazu:

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

Es scheint den Job ziemlich gut zu machen.

21
Thomas Watnedal

das funktioniert für mich in bash:

 svn status | egrep '^\?' | cut -c8- | xargs rm

Seth Reno 's ist besser:

svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r 

Es behandelt nicht versionierte Ordner und Leerzeichen in Dateinamen

Wie in den Kommentaren unten beschrieben, funktioniert dies nur für Dateien, die Subversion nicht kennt (status =?). Alles, was Subversion über weiß (einschließlich ignorierte Dateien/Ordner), wird nicht gelöscht.

Wenn Sie Subversion 1.9 oder höher verwenden, können Sie einfach den Befehl svn cleanup mit den Optionen --remove-unversioned und --remove-ignored verwenden

137
Ken

Ich bin auf diese Seite gestoßen, während ich das Gleiche suchte, allerdings nicht für einen automatisierten Build.

Nach etwas genauerem Hinsehen entdeckte ich das ' Extended Context Menu ' in TortoiseSVN. Halten Sie die Umschalttaste gedrückt und klicken Sie mit der rechten Maustaste auf die Arbeitskopie. Es gibt jetzt zusätzliche Optionen im TortoiseSVN-Menü, einschließlich ' Unversioned Items löschen ... '.

Obwohl dies möglicherweise nicht für diese spezifische Frage gilt (d. H. Im Rahmen eines automatisierten Builds), dachte ich, dass es für andere hilfreich sein könnte, die das Gleiche tun.

71
g .

Siehe: svn-clean

19
Martin

Wenn Sie sich in der Windows-Befehlszeile befinden, 

for /f "tokens=2*" %i in ('svn status ^| find "?"') do del %i

Verbesserte Version:

for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%i %j"

Wenn Sie dies in einer Batchdatei verwenden, müssen Sie den % verdoppeln:

for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%%i %%j"
9
Sukesh Nambiar

Ich habe dies zu meinem Windows-Powershell-Profil hinzugefügt

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

Linux-Befehlszeile:

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

Oder wenn einige Ihrer Dateien im Besitz von root sind:

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

Dies basiert auf Ken's Antwort. (Kens Antwort überspringt ignorierte Dateien; meine Antwort löscht sie).

5
user9876

Einfach auf Unix-Shell mit:

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

Können Sie nicht einfach an einen neuen Ort exportieren und von dort aus bauen?

4
leppie

Meine C # Konvertierung von Thomas Watnedals Python-Skript:

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

Wenn Sie tortoise svn verwenden, gibt es dafür einen versteckten Befehl. Halten Sie die Umschalttaste gedrückt, während Sie mit der rechten Maustaste auf einen Ordner klicken, um das Kontextmenü im Windows Explorer zu öffnen. Sie erhalten den Befehl "Unversioned Items löschen".

weitere Informationen finden Sie unten auf dieser Seite oder unten auf dem Screenshot, der die erweiterten Funktionen mit den grünen Sternen und die mit dem gelben Rechteck von Interesse hervorhebt.

 SVN Extended context menu vs standard menu

3
rob bentley

Subversion 1.9.0 eingeführt Option zum Entfernen nicht versionierter Elemente [1]

svn cleanup --remove-unversioned

[1] https://Subversion.Apache.org/docs/release-notes/1.9.html#svn-cleanup-options

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

Dies ist ein Unix-Shell-Befehl zum Löschen aller Dateien, die nicht der Kontrolle von Subversion unterliegen.

Anmerkungen:

  • st in svn st ist ein eingebauter Alias ​​für status, d. h. der Befehl entspricht svn status.
  • --no-ignore schließt auch Nicht-Repository-Dateien in die Statusausgabe ein. Andernfalls werden Mechanismen wie .cvsignore usw. ignoriert. Da das Ziel einen sauberen Startpunkt für Builds hat, ist dieser Schalter ein Muss
  • die Variable grep filtert die Ausgabe so, dass nur für Subversion unbekannte Dateien übrig bleiben - die Zeilen, die mit ? Listdateien beginnen, die Subversion nicht bekannt sind und die ohne die Option --no-ignore ignoriert würden
  • das Präfix bis zum Dateinamen wird über sed entfernt.
  • der Befehl xargs wird über -r angewiesen, rm nicht auszuführen, wenn die Liste der Argumente leer wäre
  • die -d '\n'-Option weist xargs an, eine Newline als Trennzeichen zu verwenden. Der Befehl funktioniert auch für Dateinamen mit Leerzeichen
  • rm -r wird verwendet, wenn vollständige Verzeichnisse (die nicht Teil des Repositorys sind) entfernt werden müssen
3
maxschlepzig

Wenn Sie TortoiseSVN in Ihrem Pfad haben und sich im richtigen Verzeichnis befinden:

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

Die Optionen werden in der TortoiseSVN-Hilfe für /command:cleanup beschrieben:

Verwenden Sie/noui, um zu verhindern, dass das Ergebnisdialogfeld angezeigt wird entweder über die Beendigung der Bereinigung oder einen Fehler Botschaft)./noprogressui deaktiviert auch den Fortschrittsdialog. /nodlg Deaktiviert die Anzeige des Bereinigungsdialogfelds, in dem der Benutzer auswählen kann, was Genau das sollte bei der Bereinigung geschehen. Die verfügbaren Aktionen können .__ sein. mit den Optionen/cleanup für die Statusbereinigung angegeben, /revert,/delunversioned,/delignored,/refreshshell und/externals.

3
stevek_mcc

Da alle anderen es tun ...

svn status | grep ^? | awk '{print $2}' | sed 's/^/.\//g' | xargs rm -R
2
JoshC13

Ich konnte nichts von dem oben genannten zum Funktionieren bringen, ohne zusätzliche Abhängigkeiten, die ich meinem automatisierten Build-System unter win32 hinzufügen wollte. Also habe ich die folgenden Ant-Befehle zusammengestellt. Beachten Sie, dass dazu der Ant-Contrib-JAR installiert werden muss (ich habe Version 1.0b3 verwendet, die neueste Version mit Ant 1.7.0).

Beachten Sie, dass dies alle nicht versionierten Dateien ohne Warnung löscht.

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

Ändern Sie für einen anderen Ordner die ${basedir}-Referenz.

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

entfernen Sie das Echo, wenn Sie sicher sind, was Sie tun möchten.

2
Aria

Reine Windows-Cmd/Bat-Lösung:

@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
1
Andriy F.

Ich stolperte über svn-clean auf meinem RH5-Rechner. Es befindet sich unter/usr/bin/svn-clean 

http://svn.Apache.org/repos/asf/Subversion/trunk/contrib/client-side/svn-clean

1
Eric Cope

Ich habe versucht, Seth Reno's Version von diese Antwort , aber es hat bei mir nicht funktioniert. Ich hatte vor Dateiname 8 Zeichen, nicht 9 in cut -c9-.

Das ist also meine Version mit sed anstelle von cut:

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

Wenn Sie cool sind mit Powershell: 

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

Entfernen Sie das Flag "-WhatIf", damit der Befehl tatsächlich die Löschvorgänge ausführt. Andernfalls wird es nur das ausgeben, was würde tun, wenn es ohne -WhatIf läuft.

1
Giscard Biamby

@zhoufei Ich habe deine Antwort getestet und hier ist die aktualisierte Version:

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"
  • Sie müssen zwei %-Markierungen vor G und H verwenden
  • Wechseln Sie die Reihenfolge: Entfernen Sie zuerst alle Dateien und anschließend alle Verzeichnisse
  • (optional :) Anstelle von %~1 kann ein beliebiger Verzeichnisname verwendet werden. Ich habe dies als Funktion in einer bat-Datei verwendet, daher ist %~1 der erste Eingabeparameter
1
Nikola

Könnte auch eine andere Option beitragen

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

Die /(config|.ini)/ ist für meine eigenen Zwecke.

Vielleicht ist es eine gute Idee, dem Befehl svn den Befehl --no-ignore hinzuzufügen

1
user1299374

Ein sauberer Weg, dies in Perl zu tun, wäre:

#!/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
J. T. Marsh

Für die Leute, die dies gerne mit Perl anstelle von Python, Unix Shell, Java usw. tun. Hiermit ein kleines Perl-Skript, das auch den Jib ausführt.

Hinweis: Dadurch werden auch alle nicht versionierten Verzeichnisse entfernt

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

C # -Code-Snipet oben hat für mich nicht funktioniert - ich habe tortoise svn client und die Zeilen sind etwas anders formatiert. Hier ist das gleiche Code-Snipet wie oben, nur umgeschrieben in Funktion und unter Verwendung von Regex.

        /// <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
0
TarmoPikaro

Ich habe auch folgendes gefunden und verwendet: Svn status --no-ignore | awk '/ ^?/{print $ 2}' | xargs rm

0
chataros

Wenn Sie keinen Code schreiben möchten, führt svn2.exe aus svn2svn dies aus. Außerdem gibt es einen Artikel zur Implementierung. Gelöschte Ordner und Dateien werden in den Papierkorb verschoben.

Führen Sie "svn2.exe sync [Pfad]" aus. 

0
dB.

Für Leute unter Windows, die die Verwendung eines Tools mit Ausnahme der Standardbefehle von MS-Dos vermeiden möchten, finden Sie hier eine Lösung:

FOR/F "token = 1 * delims ="% G IN ('svn st ^ | findstr "^?"') DO rd/s/q "% H"

FOR/F "token = 1 * delims ="% G IN ('svn st ^ | findstr "^?"') DO del/s/f/q "% H"

  • svn st zeigt den Status aller Dateien und Ordner in der Arbeitskopie an
  • findstr sucht nach jeder Zeile, die mit '?' beginnt, was bedeutet, dass die Datei/der Ordner nicht versioniert ist
  • FOR wird als Trennzeichen verwendet und nimmt die Token nach dem ersten (das erste ist% G, der Rest ist% H) Auf diese Weise extrahieren wir die Datei/den Ordner aus der Ausgabe des Befehls svn st.
  • rd löscht Ordner, del löscht Dateien.
0
zhoufei

Verwenden von TortoiseSVN: * Klicken Sie mit der rechten Maustaste auf den Arbeitskopieordner, und halten Sie die Umschalttaste gedrückt. * Wählen Sie "unversionierte Elemente löschen".

Wie kann ich alle nicht versionierten/ignorierten Dateien/Ordner in meiner Arbeitskopie löschen?

0
umpirsky

Ich würde dies als Kommentar zu Thomas Watnedals Antwort hinzufügen , kann es aber noch nicht.

Ein geringfügiges Problem (das Windows nicht betrifft) ist, dass nur nach Dateien oder Verzeichnissen gesucht wird. Für Unix-ähnliche Systeme, in denen möglicherweise symbolische Links vorhanden sind, muss die Zeile geändert werden:

if os.path.isfile(fullpath):

zu

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

um auch Links zu entfernen.

Für mich ändere die letzte Zeile if match: removeall(match.group(1)) in

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

so dass es zeigt, was es entfernt hat, war auch nützlich.

Je nach Anwendungsfall ist der ?[\?ID]-Teil des regulären Ausdrucks möglicherweise besser als ?[\?I], da die D auch gelöschte Dateien entfernt, die der Versionskontrolle unterliegen. Ich möchte dies verwenden, um einen sauberen, eingecheckten Ordner zu erstellen, daher sollten sich keine Dateien in einem D-Zustand befinden.

0
Michael Firth

Ich habe ~ 3 Stunden gebraucht, um das zu generieren. Es würde 5 Minuten dauern, um dies in Unix zu tun .. Das Hauptproblem war: Leerzeichen in Namen für Win-Ordner, Unmöglichkeit, %% i zu bearbeiten, und Problem beim Definieren von vars in der Win-Cmd-Schleife.

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
Ilya Rosman