Supprimer automatiquement les fichiers sans version 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’en ai besoin pour obtenir des résultats plus fiables dans ma version automatique de VMware.)

J’utilise ce script python pour faire cela:

 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.comstack('^ ?[\?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 bien faire le travail.

cela fonctionne pour moi en bash:

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

Seth Reno est mieux:

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

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

Selon les commentaires ci-dessous, cela ne fonctionne que sur les fichiers que subversion ne connaît pas (status =?). Tout ce que subversion connaît (y compris les fichiers / dossiers ignorés) ne sera pas supprimé.

Si vous utilisez subversion 1.9 ou supérieur, vous pouvez simplement utiliser la commande svn cleanup avec les options –remove-unversioned et –remove-ignoreored

J’ai parcouru cette page en cherchant à faire la même chose, mais pas pour une génération automatisée.

Après un peu plus de recherche, j’ai découvert le ” Menu contextuel étendu ” dans TortoiseSVN. Maintenez la touche Maj enfoncée et cliquez avec le bouton droit sur la copie de travail. Il y a maintenant des options supplémentaires dans le menu TortoiseSVN, y compris ” Supprimer les éléments sans version … “.

Bien que cela ne soit peut-être pas applicable à cette question spécifique (c.-à-d. Dans le contexte d’une compilation automatisée), j’ai pensé que cela pourrait être utile pour ceux qui cherchent à faire la même chose.

Voir: svn-clean

Si vous êtes sur la 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 l’utilisez 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 $_.subssortingng(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).

Vous ne pouvez pas simplement faire une exportation vers un nouvel emplacement et construire à partir de là?

Faites-le simplement sur unix-shell avec:

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

Ma conversion en C # du script Python 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)) { ssortingng line = process.StandardOutput.ReadLine(); while (line != null) { if (line.Length > 7) { if (line[0] == '?') { ssortingng relativePath = line.Subssortingng(7); Console.WriteLine(relativePath); ssortingng 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 

Ceci est une commande shell unix pour supprimer tous les fichiers qui ne sont pas sous le contrôle de subversion.

Remarques:

  • le st dans svn st est un alias intégré pour status , c.-à-d. que la commande est équivalente à svn status
  • --no-ignore inclut également les fichiers non référentiels dans la sortie d’état, sinon il est .cvsignore via des mécanismes tels que .cvsignore etc. – le but étant d’avoir un sharepoint départ propre pour les builds, ce switch est un must
  • le grep filtre la sortie de sorte que seuls les fichiers inconnus de subversion soient laissés – les lignes commençant par ? répertorie 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 comportant des espaces.
  • rm -r est utilisé si des répertoires complets (qui ne font pas partie du référentiel) doivent être supprimés

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 dialog de résultat de s’afficher soit en indiquant que le nettoyage est terminé ou en affichant un message d’erreur). / noprogressui désactive également la boîte de dialog de progression. / nodlg désactive l’affichage de la boîte de dialog de nettoyage où l’utilisateur peut choisir exactement ce qui doit être fait lors du nettoyage. Les actions disponibles peuvent être spécifiées avec les options / nettoyage pour le nettoyage de l’état, / revert, / delunversenced, / delignored, / refreshshell et / externals.

Si vous utilisez tortoise svn, il existe une commande cachée pour ce faire. Maintenez la touche Maj enfoncée en cliquant avec le bouton droit sur un dossier pour lancer le menu contextuel dans l’explorateur Windows. Vous obtiendrez une commande “Supprimer les éléments sans version”.

voir le bas de cette page pour des détails, ou la capture d’écran ci-dessous qui met en évidence les fonctionnalités étendues avec les écanvass vertes, et celle d’intérêt avec le rectangle jaune …

Menu contextuel SVN étendu vs menu standard

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

Notez que cela supprime tous les fichiers sans version sans avertissement.

                                

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

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

Supprimez l’écho si c’est sûr ce que vous voulez faire.

Puisque tout le monde le fait …

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

Pourrait aussi bien consortingbuer une autre option

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

Le /(config|.ini)/ est à mes propres fins.

Et peut-être une bonne idée d’append –no-ignore à la commande svn

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

http://svn.apache.org/repos/asf/subversion/trunk/consortingb/client-side/svn-clean

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 

J’ai essayé la version de Seth Reno 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é dans cut -c9- .

Voici donc 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 | ?{$_.SubSsortingng(0,1).Equals("?")} | foreach { remove-item -Path (join-Path .\ $_.Replace("?","").Trim()) -WhatIf } 

Supprimez l’indicateur -WhatIf pour que la commande exécute réellement les suppressions. Sinon, il produira simplement ce qu’il ferait s’il était 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" 
  • Vous devez utiliser deux points de % devant G et H
  • Changez l’ordre: supprimez d’abord tous les fichiers, puis supprimez tous les répertoires.
  • (optionnel 🙂 A la place de %~1 on peut utiliser n’importe quel nom de répertoire, je l’ai utilisé comme fonction dans un fichier bat, donc %~1 est le premier paramètre d’entrée

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

Exécutez “svn2.exe sync [chemin]”.

Pour les personnes qui aiment faire cela avec perl au lieu de python, shell Unix, java, etc. Voici un petit script perl qui fait aussi le jib.

Remarque: ceci supprime également tous les répertoires sans version

 #!perl use ssortingct; 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(); 

Utiliser 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 sans version”

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

Une façon propre de le faire dans 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 () 

J’ai utilisé ~ 3 heures pour générer cela. Cela prendrait 5 minutes pour le faire dans Unix. Le problème principal était: les espaces dans les noms pour les dossiers Win, l’impossibilité d’éditer %% i et le problème avec la définition de 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! ) 

Le code du code C # ci-dessus ne fonctionnait pas pour moi – j’ai le client de tortue svn, et les lignes sont formatées légèrement différemment. Voici le même code snipet que ci-dessus, seulement réécrit pour fonctionner et en utilisant regex.

  ///  /// Cleans up svn folder by removing non committed files and folders. ///  void CleanSvnFolder( ssortingng 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)) { ssortingng line = process.StandardOutput.ReadLine(); while (line != null) { var m = Regex.Match(line, "\\? +(.*)"); if( m.Groups.Count >= 2 ) { ssortingng relativePath = m.Groups[1].ToSsortingng(); ssortingng 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 

Pour les utilisateurs de Windows qui souhaitent éviter d’utiliser n’importe quel outil, à l’exception des commandes standard MS-Dos, voici une solution:

FOR / F “jetons = 1 * delims =”% G IN (‘svn st ^ | findstr “^?”‘) DO rd / s / q “% H”

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

  • svn st affichera le statut de chaque fichier et dossier dans la copie de travail
  • findstr cherchera 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 rest est% H). De cette façon, nous travaillons sur le fichier / dossier à partir de la sortie de la commande svn st.
  • rd va supprimer les dossiers, del supprime les fichiers.

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

Un problème mineur avec celui-ci (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)) dans

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

afin qu’il affiche ce qu’il est en train de supprimer était également utile.

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