web-dev-qa-db-fra.com

Supprimer automatiquement les fichiers non versionnés de Subversion

Est-ce que quelqu'un connaît un moyen de supprimer récursivement tous les fichiers d'une copie de travail qui ne sont pas sous contrôle de version? (J'ai besoin de cela pour obtenir des résultats plus fiables dans mon build VMware automatique.)

108
Stefan Schultze

Modifier:

Subversion 1.9.0 a introduit une option pour cela:

svn cleanup --remove-unversioned

Avant cela, j'utilise ce script python pour le faire:

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

Il semble faire assez bien le travail.

21
Thomas Watnedal

ça marche pour moi en bash:

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

Seth Reno s est mieux:

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

Il gère les dossiers et les espaces non versionnés dans les noms de fichiers

Selon les commentaires ci-dessous, cela ne fonctionne que sur les fichiers inconnus de Subversion (status =?). Tout ce que Subversion sait (y compris les fichiers/dossiers ignorés) ne sera pas supprimé.

Si vous utilisez Subversion 1.9 ou une version ultérieure, vous pouvez simplement utiliser la commande svn cleanup avec les options --remove-unversION et --remove-ignored

137
Ken

J'ai parcouru cette page en cherchant à faire la même chose, mais pas pour une construction automatisée.

Après un peu plus de temps, j'ai découvert le 'Extended Context Menu' dans TortoiseSVN. Maintenez la touche Maj enfoncée et cliquez avec le bouton droit de la souris sur la copie de travail. Il existe maintenant des options supplémentaires dans le menu TortoiseSVN, notamment 'Supprimer les éléments non versionnés ...'.

Bien que cela ne soit peut-être pas applicable à cette question spécifique (c'est-à-dire dans le contexte d'une construction automatisée), j'ai pensé que cela pourrait être utile aux autres personnes cherchant à faire de même.

71
g .

Voir: svn-clean

19
Martin

Si vous êtes en ligne de commande Windows, 

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

Version améliorée:

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

Si vous utilisez ceci dans un fichier de commandes, vous devez doubler le %:

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

J'ai ajouté ceci à mon profil windows powershell

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

Ligne de commande Linux:

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

Ou, si certains de vos fichiers appartiennent à root:

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

Ceci est basé sur la réponse de Ken. (La réponse de Ken ignore les fichiers ignorés; ma réponse les supprime).

5
user9876

Il suffit de le faire sur unix-shell avec:

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

Ne pouvez-vous pas simplement exporter vers un nouvel emplacement et construire à partir de là?

4
leppie

Ma conversion C # du script Python de Thomas Watnedals:

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

Si vous utilisez tortoise svn, il existe une commande cachée pour le faire. Maintenez la touche Maj enfoncée tout en cliquant avec le bouton droit de la souris sur un dossier pour lancer le menu contextuel dans Windows Explorer. Vous obtiendrez une commande "Supprimer les éléments non versionnés".

voir le bas de cette page pour plus de détails, ou la capture d'écran ci-dessous qui met en évidence les traits étendus avec les étoiles vertes et celle d'intérêt avec le rectangle jaune ...

 SVN Extended context menu vs standard menu

3
rob bentley

Subversion 1.9.0 introduit une option pour supprimer les éléments non versionnés [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

Il s’agit d’une commande unix pour supprimer tous les fichiers qui ne sont pas sous le contrôle de Subversion.

Remarques:

  • st dans svn st est un alias intégré pour status, c’est-à-dire que la commande est équivalente à svn status
  • --no-ignore inclut également des fichiers non-référentiels dans la sortie de statut, sinon ignore via des mécanismes tels que .cvsignore, etc. - l'objectif étant de disposer d'un point de départ propre pour les constructions, ce commutateur est indispensable.
  • la grep filtre la sortie de manière à ne conserver que les fichiers inconnus de Subversion - les lignes commençant par ? répertorient les fichiers inconnus de Subversion qui seraient ignorés sans l'option --no-ignore
  • le préfixe jusqu'au nom du fichier est supprimé via sed
  • la commande xargs reçoit l'instruction via -r de ne pas exécuter rm, lorsque la liste d'arguments serait vide
  • l'option -d '\n' indique à xargs d'utiliser une nouvelle ligne comme délimiteur, de sorte que la commande fonctionne également pour les noms de fichiers avec des espaces
  • rm -r est utilisé dans le cas où des répertoires complets (qui ne font pas partie du référentiel) doivent être supprimés
3
maxschlepzig

Si vous avez TortoiseSVN sur votre chemin et que vous êtes dans le bon répertoire:

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

Les options sont décrites dans l'aide de TortoiseSVN pour /command:cleanup:

Utilisez/noui pour empêcher la boîte de dialogue de résultat d’être affichée soit en indiquant que le nettoyage est terminé ou en affichant une erreur message)./noprogressui désactive également le dialogue de progression. /nodlg désactive l'affichage de la boîte de dialogue de nettoyage dans laquelle l'utilisateur peut choisir quoi exactement devrait être fait dans le nettoyage. Les actions disponibles peuvent être spécifié avec les options/cleanup pour le nettoyage du statut, /revert,/delunversional,/delignored,/refreshshell et/externals.

3
stevek_mcc

Puisque tout le monde le fait ...

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

Je ne pouvais obtenir aucun des éléments ci-dessus pour fonctionner sans dépendances supplémentaires que je ne voulais pas avoir à ajouter à mon système de construction automatisé sur win32. J'ai donc rassemblé les commandes Ant suivantes - notez qu'elles nécessitent l'installation du fichier JAR Ant-contrib (j'utilisais la version 1.0b3, la plus récente, avec Ant 1.7.0).

Notez que cela supprime tous les fichiers non versionnés sans avertissement.

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

Pour un autre dossier, changez la référence ${basedir}.

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

supprimez l'écho si c'est sûr de ce que vous voulez faire.

2
Aria

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

Je suis tombé sur svn-clean sur ma machine RH5. Il est situé dans/usr/bin/svn-clean 

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

1
Eric Cope

J'ai essayé Seth Reno version de cette réponse mais cela n'a pas fonctionné pour moi. J'ai eu 8 caractères avant le nom de fichier, pas 9 utilisés dans cut -c9-.

Donc, voici ma version avec sed au lieu de cut:

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

Si vous êtes cool avec powershell: 

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

Retirez l'indicateur -WhatIf pour que la commande effectue réellement les suppressions. Sinon, il ne fera que sortir ce qu'il ferait faire s'il est exécuté sans le -WhatIf.

1
Giscard Biamby

@zhoufei J'ai testé votre réponse et voici la version mise à jour:

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"
  • Vous devez utiliser deux marques % devant G et H
  • Changer l'ordre: d'abord supprimer tous les fichiers, puis tous les répertoires
  • (facultatif :) À la place de %~1, vous pouvez utiliser n'importe quel nom de répertoire. Je l'ai utilisé comme fonction dans un fichier bat. Ainsi, %~1 est le premier paramètre d'entrée.
1
Nikola

Pourrait aussi contribuer une autre option

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

Le /(config|.ini)/ est pour mes propres besoins.

Et peut-être une bonne idée d'ajouter --no-ignore à la commande svn

1
user1299374

Une façon propre de faire cela en Perl serait:

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

Pour les personnes qui aiment faire cela avec Perl au lieu de python, Unix Shell, Java, etc.

Remarque: Ceci supprime également tous les répertoires non versionnés.

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

Le snipet de code C # ci-dessus ne fonctionnait pas pour moi. J'ai Tortoise svn client et les lignes sont formatées légèrement différemment. Voici le même snipet de code que ci-dessus, seulement réécrit pour fonctionner et en utilisant 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

J'ai également trouvé et utilisé les éléments suivants: Svn status --no-ignore | awk '/ ^?/{print $ 2}' | xargs rm

0
chataros

Si vous ne voulez écrire aucun code, svn2.exe à partir de svn2svn fait ceci, il y a aussi un article sur la façon dont il est implémenté. Les dossiers et fichiers supprimés sont mis dans la corbeille.

Exécutez "svn2.exe sync [chemin]". 

0
dB.

Pour les utilisateurs de Windows qui ne souhaitent utiliser aucun outil, à l'exception des commandes standard MS-Dos, voici une solution:

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

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

  • svn st affichera l’état de chaque fichier et dossier dans la copie de travail
  • findstr recherchera chaque ligne commençant par '?', ce qui signifie que le fichier/dossier n'est pas versionné
  • FOR utilisera comme délimiteurs et prendra les jetons après le premier (le premier est% G, le reste est% H) De cette manière, nous extrayons le fichier/dossier de la sortie de la commande svn st.
  • rd supprimera les dossiers, del supprimera les fichiers.
0
zhoufei

Avec TortoiseSVN: * faites un clic droit sur le dossier de la copie de travail tout en maintenant la touche Maj enfoncée * choisissez "supprimer les éléments non versionnés"

Comment puis-je supprimer tous les fichiers/dossiers non versionnés/ignorés de ma copie de travail?

0
umpirsky

J'ajouterais ceci comme commentaire à à la réponse de Thomas Watnedal , mais je ne peux pas encore.

Un problème mineur avec cela (qui n'affectera pas Windows) est qu'il ne vérifie que les fichiers ou les répertoires. Pour les systèmes de type Unix où des liens symboliques peuvent être présents, il est nécessaire de changer de ligne:

if os.path.isfile(fullpath):

à

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

supprimer également les liens.

Pour moi, changer la dernière ligne if match: removeall(match.group(1)) en

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

de sorte qu'il affiche ce qu'il supprime était également utile.

Selon le cas d'utilisation, la partie ?[\?ID] de l'expression régulière peut être meilleure que ?[\?I], car la D supprime également les fichiers supprimés, qui étaient sous contrôle de version. Je souhaite l'utiliser pour créer un dossier propre et archivé, de sorte qu'il ne devrait y avoir aucun fichier dans un état D.

0
Michael Firth

J'ai utilisé ~ 3 heures pour générer cela. Cela prendrait 5 minutes pour le faire sous Unix . Le problème principal était: les espaces dans les noms des dossiers Win, l'impossibilité de modifier %% i et le problème de définition des vars dans la boucle 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
Ilya Rosman