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.)
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.
ç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
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.
Voir: svn-clean
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"
J'ai ajouté ceci à mon profil windows powershell
function svnclean {
svn status | foreach { if($_.StartsWith("?")) { Remove-Item $_.substring(8) -Verbose } }
}
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).
Il suffit de le faire sur unix-shell avec:
rm -rf `svn st . | grep "^?" | cut -f2-9 -d' '`
Ne pouvez-vous pas simplement exporter vers un nouvel emplacement et construire à partir de là?
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();
}
}
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 ...
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
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.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
sed
xargs
reçoit l'instruction via -r
de ne pas exécuter rm
, lorsque la liste d'arguments serait vide-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 espacesrm -r
est utilisé dans le cas où des répertoires complets (qui ne font pas partie du référentiel) doivent être supprimésSi 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.
Puisque tout le monde le fait ...
svn status | grep ^? | awk '{print $2}' | sed 's/^/.\//g' | xargs rm -R
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 "${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>
Pour un autre dossier, changez la référence ${basedir}
.
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.
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
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
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
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.
@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"
%
devant G et H%~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.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
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 ()
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();
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
J'ai également trouvé et utilisé les éléments suivants: Svn status --no-ignore | awk '/ ^?/{print $ 2}' | xargs rm
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]".
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"
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?
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
.
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!
)