¿Alguien sabe una forma de eliminar de forma recursiva todos los archivos en una copia de trabajo que no están bajo control de versiones? (Necesito esto para obtener resultados más confiables en mi VMware de compilación automática).
fuente
¿Alguien sabe una forma de eliminar de forma recursiva todos los archivos en una copia de trabajo que no están bajo control de versiones? (Necesito esto para obtener resultados más confiables en mi VMware de compilación automática).
Editar:
Subversion 1.9.0 introdujo una opción para hacer esto:
svn cleanup --remove-unversioned
Antes de eso, uso este script de Python para hacer eso:
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))
Parece hacer el trabajo bastante bien.
svn cleanup --remove-unversioned
es mejor. Y es para Subversion 1.9.0 (esta versión es de 2015). Es estable y estándar.
esto funciona para mí en bash:
svn status | egrep '^\?' | cut -c8- | xargs rm
El de Seth Reno es mejor:
svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r
Maneja carpetas y espacios no versionados en nombres de archivos.
Según los comentarios a continuación, esto solo funciona en archivos que Subversion no conoce (estado =?). Todo lo que hace la subversión sabe de (incluyendo ficheros ignorados / carpetas) no se eliminarán.
Si está usando subversion 1.9 o superior, simplemente puede usar el comando svn cleanup con las opciones --remove-unversioned y --remove-ignored
svn status | grep "^?" | awk '{print $2}' | xargs -d \\n rm -r
Me encontré con esta página mientras buscaba hacer lo mismo, aunque no para una compilación automática.
Después de buscar un poco más descubrí el ' Menú contextual extendido ' en TortoiseSVN. Mantenga presionada la tecla Mayús y haga clic con el botón derecho en la copia de trabajo. Ahora hay opciones adicionales en el menú de TortoiseSVN que incluyen ' Eliminar elementos no versionados ... '.
Aunque tal vez no sea aplicable para esta pregunta específica (es decir, dentro del contexto de una compilación automatizada), pensé que podría ser útil para otros que buscan hacer lo mismo.
Si está en la línea de comandos de Windows,
for /f "tokens=2*" %i in ('svn status ^| find "?"') do del %i
Versión mejorada:
for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%i %j"
Si usa esto en un archivo por lotes, necesita duplicar %
:
for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%%i %%j"
Agregué esto a mi perfil de Windows PowerShell
function svnclean {
svn status | foreach { if($_.StartsWith("?")) { Remove-Item $_.substring(8) -Verbose } }
}
--no-ignore
a svn status
y -Recurse
aRemove-Item
Línea de comandos de Linux:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | xargs -d \\n rm -r
O, si algunos de sus archivos son propiedad de root:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | sudo xargs -d \\n rm -r
Esto se basa en la respuesta de Ken. (La respuesta de Ken omite los archivos ignorados; mi respuesta los elimina).
Simplemente hazlo en unix-shell con:
rm -rf `svn st . | grep "^?" | cut -f2-9 -d' '`
¿No puede simplemente exportar a una nueva ubicación y construir desde allí?
Si tiene TortoiseSVN en su ruta y está en el directorio correcto:
TortoiseProc.exe /command:cleanup /path:"%CD%" /delunversioned /delignored /nodlg /noui
Las opciones se describen en la ayuda de TortoiseSVN para /command:cleanup
:
Use / noui para evitar que aparezca el cuadro de diálogo de resultados, ya sea para informar sobre la finalización de la limpieza o para mostrar un mensaje de error). / noprogressui también deshabilita el diálogo de progreso. / nodlg deshabilita mostrar el diálogo de limpieza donde el usuario puede elegir qué se debe hacer exactamente en la limpieza. Las acciones disponibles se pueden especificar con las opciones / cleanup para limpieza de estado, / revert, / delunversioned, / delignored, / refreshshell y / externals.
Si está utilizando tortoise svn, hay un comando oculto para hacer esto. Mantenga presionada la tecla Mayús mientras hace clic con el botón derecho en una carpeta para iniciar el menú contextual en el explorador de Windows. Obtendrá un comando "Eliminar elementos no versionados".
consulte la parte inferior de esta página para obtener más detalles, o la captura de pantalla a continuación que resalta las características extendidas con las estrellas verdes y la de interés con el rectángulo amarillo ...
Subversion 1.9.0 introdujo la opción para eliminar elementos no versionados [1]
svn cleanup --remove-unversioned
[1] https://subversion.apache.org/docs/release-notes/1.9.html#svn-cleanup-options
Mi conversión en C # de la secuencia de comandos 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();
}
}
svn st --no-ignore | grep '^[?I]' | sed 's/^[?I] *//' | xargs -r -d '\n' rm -r
Este es un comando de shell de Unix para eliminar todos los archivos que no están bajo el control de Subversion.
Notas:
st
in svn st
es un alias integrado para status
, es decir, el comando es equivalente asvn status
--no-ignore
también incluye archivos que no son de repositorio en la salida de estado; de lo contrario, se ignora a través de mecanismos como, .cvsignore
etc., ya que el objetivo es tener un punto de partida limpio para las compilaciones, este cambio es imprescindiblegrep
filtros de salida de tal manera que solo quedan archivos desconocidos para la subversión - las líneas que comienzan con la ?
lista de archivos desconocidos para la subversión que serían ignorados sin la --no-ignore
opciónsed
xargs
comando recibe instrucciones a través de -r
que no se ejecute rm
, cuando la lista de argumentos estaría vacía-d '\n'
opción dicexargs
que use una nueva línea como delimitador, por lo que el comando también funciona para nombres de archivo con espaciosrm -r
se utiliza en caso de que sea necesario eliminar directorios completos (que no forman parte del repositorio)No pude hacer que nada de lo anterior funcione sin dependencias adicionales que no quería tener que agregar a mi sistema de compilación automatizado en win32. Así que reuní los siguientes comandos Ant; tenga en cuenta que estos requieren que se instale Ant-contrib JAR (estaba usando la versión 1.0b3, la última, con Ant 1.7.0).
Tenga en cuenta que esto elimina todos los archivos sin versión sin previo aviso.
<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>
Para una carpeta diferente, cambie la ${basedir}
referencia.
svn status --no-ignore | awk '/^[I\?]/ {system("echo rm -r " $2)}'
elimine el eco si está seguro de lo que quiere hacer.
/bin/sh
y n rm
procesos bifurcados.
Como todos los demás lo están haciendo ...
svn status | grep ^? | awk '{print $2}' | sed 's/^/.\//g' | xargs rm -R
También podría aportar otra opción
svn status | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'
El /(config|.ini)/ es para mis propios fines.
Y podría ser una buena idea agregar --no-ignore al comando svn
Me encontré con svn-clean en mi máquina RH5. Está ubicado en / usr / bin / svn-clean
http://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svn-clean
Solución pura de 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
He tratado de Seth Reno versión de esta respuesta pero no funcionó para mí. He tenido 8 caracteres antes del nombre de archivo, no 9 usados encut -c9-
.
Entonces esta es mi versión con en sed
lugar de cut
:
svn status | grep ^\? | sed -e 's/\?\s*//g' | xargs -d \\n rm -r
Si estás de acuerdo con powershell:
svn status --no-ignore | ?{$_.SubString(0,1).Equals("?")} | foreach { remove-item -Path (join-Path .\ $_.Replace("?","").Trim()) -WhatIf }
Saque el indicador -WhatIf para que el comando realmente realice las eliminaciones. De lo contrario, solo mostrará lo que haría si se ejecuta sin el -WhatIf.
Agregaría esto como un comentario a la respuesta de Thomas Watnedal. , pero aún no puedo.
Un problema menor con él (que no afectará a Windows) es que solo busca archivos o directorios. Para sistemas similares a Unix donde pueden estar presentes enlaces simbólicos, es necesario cambiar la línea:
if os.path.isfile(fullpath):
a
if os.path.isfile(fullpath) or os.path.islink(fullpath):
para eliminar también los enlaces.
Para mí, cambiar la última línea if match: removeall(match.group(1))
por
if match:
print "Removing " + match.group(1)
removeall(match.group(1))
para que muestre lo que está eliminando también fue útil.
Dependiendo del caso de uso, la ?[\?ID]
parte de la expresión regular puede ser mejor ?[\?I]
, ya que D
también elimina los archivos eliminados, que estaban bajo control de versiones. Quiero usar esto para compilar en una carpeta limpia y registrada, por lo que no debería haber archivos en un D
estado.
@zhoufei Probé tu respuesta y aquí está la versión actualizada:
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"
%
marcas delante de G y H%~1
se puede usar cualquier nombre de directorio, lo usé como una función en un archivo bat, por lo que %~1
es el primer parámetro de entradaSi no desea escribir ningún código, svn2.exe de svn2svn hace esto, también hay un artículo sobre cómo se implementa. Las carpetas y archivos eliminados se colocan en la papelera de reciclaje.
Ejecute "svn2.exe sync [ruta]".
Para las personas a las que les gusta hacer esto con perl en lugar de python, shell de Unix, java, etc. A continuación, un pequeño script en perl que también hace el jib.
Nota: Esto también elimina todos los directorios no versionados.
#!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();
Usando TortoiseSVN: * haga clic con el botón derecho en la carpeta de la copia de trabajo, mientras mantiene presionada la tecla Mayús * elija "eliminar elementos no versionados"
Una forma limpia de hacer esto en PERL sería:
#!/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 ()
Usé ~ 3 horas para generar esto. Tardaría 5 minutos en hacerlo en Unix. El problema principal era: espacios en los nombres de las carpetas de Win, imposibilidad de editar %% iy problema con la definición de vars en el bucle cmd de Win.
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!
)
El fragmento de código C # anterior no funcionó para mí: tengo un cliente svn de tortuga y las líneas tienen un formato ligeramente diferente. Aquí está el mismo fragmento de código que el anterior, solo reescrito para funcionar y usar expresiones regulares.
/// <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
hg purge --all
en Mercurial.