自动删除Subversion未版本化的文件

有没有人知道一种方式recursion删除工作副本中的所有文件不受版本控制? (我需要这个在我的自动构buildVMware中获得更可靠的结果。)

我使用这个python脚本来做到这一点:

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

这似乎做得很好。

这在bash中适用于我:

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

塞斯里诺的更好:

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

它处理文件名中的未版本化的文件夹和空格

根据下面的评论,这只适用于颠覆不知道的文件(状态=?)。 任何颠覆者所知(包括忽略的文件/文件夹)都不会被删除。

如果您使用的是Subversion 1.9或更高版本,您可以简单地使用svn cleanup命令,并带有–remove-unversioned和–remove-ignored选项

我跑过这个页面,同时寻找做同样的事情,虽然不是一个自动构build。

在看了一下后,我发现了TortoiseSVN中的“ 扩展上下文菜单 ”。 按住shift键并右键单击工作副本。 现在TortoiseSVN菜单下还有其他选项,包括“ 删除未版本化的项目… ”。

虽然也许不适用于这个特定的问题(即在自动构build的情况下),但我认为这对于那些希望做同样事情的人可能会有所帮助。

请参阅: svn-clean

如果你在Windows命令行上,

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

改良版:

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

如果你在一个batch file中使用这个,你需要把%

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

我把这个添加到我的Windows PowerShell的个人资料

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

Linux命令行:

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

或者,如果您的某些文件归root用户所有:

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

这是基于肯的答案。 (肯的答案跳过忽略的文件;我的回答删除它们)。

你不能只是出口到一个新的位置,并从那里build立?

只要在unix-shell上用:

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

Thomas Watnedals Python脚本的C#转换:

 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 

这是一个unix shell命令,用于删除不在颠覆控制下的所有文件。

笔记:

  • svn st是状态的内build别名,即该命令等同于svn status
  • --no-ignore还包括状态输出中的非存储库文件,否则通过像.cvsignore等机制忽略 – 因为目标是有一个干净的起点build立这个开关是必须的
  • grep过滤输出,只保留subversion未知的文件 – 以?开头的行? 列出未知的文件,在没有--no-ignore选项的情况下会被忽略
  • 直到文件名的前缀是通过sed删除的
  • 当参数列表为空时,通过-r指示xargs命令不执行rm
  • -d '\n'选项告诉xargs使用换行符作为分隔符,这个命令也适用于带有空格的文件名
  • rm -r用于完整目录(不是存储库的一部分)需要被删除

如果您的path上有TortoiseSVN ,并且位于正确的目录中:

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

这些选项在TortoiseSVN帮助/command:cleanup进行了描述/command:cleanup

使用/ noui来防止结果对话框popup,告诉清理完成或显示错误信息)。 / noprogressui也禁用进度对话框。 / nodlg禁用显示清理对话框,用户可以select清理中应该完成的工作。 可用的操作可以通过选项/清理来指定状态清理,/还原,/删除版本,/撤销,/ refreshshell和/外部。

如果你使用龟svn有一个隐藏的命令来做到这一点。 按住Shift键的同时右键单击文件夹,在Windows资源pipe理器中启动上下文菜单。 你会得到一个“删除未版本化的项目”命令。

有关详细信息,请参阅此页面的底部,或者下面的屏幕截图突出显示绿色星星的扩展function,以及黄色矩形的感兴趣的function。

SVN扩展上下文菜单vs标准菜单

我不能得到任何上述的工作没有额外的依赖关系,我不想在win32上添加到我的自动生成系统。 所以我把下面的Ant命令放在一起 – 注意这些需要安装Ant-contrib JAR(我使用的版本是1.0b3,最新的版本是Ant 1.7.0)。

注意这会删除所有未版本控制的文件而不会有警告。

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

对于不同的文件夹,更改${basedir}引用。

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

删除回声,如果这是确定你想要做什么。

由于其他人都在这样做…

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

还可以提供另一种select

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

/(config|.ini)/是为了我自己的目的。

对于svn命令添加–no-ignore可能是一个好主意

我在RH5机器上偶然发现了svn-clean。 它位于/ usr / bin / svn-clean

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

纯windows cmd / bat解决scheme:

 @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 

我已经从这个答案尝试塞思里诺的版本,但它并没有为我工作。 我已经有8个字符在文件名之前,而不是9用于cut -c9-

所以这是我用sed代替cut版本:

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

如果你对PowerShell很酷:

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

取出-WhatIf标志使命令实际执行删除操作。 否则,它只会输出如果没有-WhatIf而运行的话。

如果你不想编写任何代码,svn2svn的svn2.exe可以做到这一点,还有一篇关于如何实现的文章 。 删除的文件夹和文件被放入回收站。

运行“svn2.exe sync [path]”。

对于那些喜欢用perl而不是python,Unix shell,java等来做这件事的人来说。

注意:这也删除所有未版本化的目录

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

使用TortoiseSVN:*右键单击工作副本文件夹,同时按住shift键*select“删除未版本化的项目”

我如何删除我的工作副本中的所有未版本化/忽略的文件/文件夹?

在PERL中这样做的一个简单的方法是:

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

我用了〜3个小时来产生这个。 在Unix中这将需要5分钟的时间。 主要问题是:Win文件夹名称中的空格,无法编辑%% i以及在Win cmd循环中定义variables时出现问题。

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

上面的C#代码snipet没有为我工作 – 我有乌龟svn客户端,行格式稍有不同。 这里是与上面相同的代码snipet,只是重写function和使用正则expression式。

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

对于希望避免使用除标准MS-Dos命令之外的任何工具的Windows用户,请提供以下解决scheme:

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

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

  • svn st会显示工作副本中每个文件和文件夹的状态
  • findstr会查找以'?'开始的每一行,这意味着文件/文件夹未版本化
  • FOR将用作分隔符,并在第一个(第一个是%G,其余的是%H)之后接受令牌。这样我们就从svn st命令输出中提取文件/文件夹。
  • rd会删除文件夹,del会删除文件。

我会添加这个作为托马斯Watnedal答案的评论,但还不能。

它的一个小问题(不会影响Windows)是它只检查文件或目录。 对于像可能存在符号链接的Unix系统,有必要改变这一行:

 if os.path.isfile(fullpath): 

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

也删除链接。

对我来说, if match: removeall(match.group(1)) ,将最后一行if match: removeall(match.group(1))

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

以便它显示它正在删除的是有用的。

根据用例,正则expression式的?[\?ID]部分可能会更好?[\?I] ,因为D还会删除受版本控制的已删除文件。 我想用它来build立一个干净的,签入的文件夹,所以不应该有D状态的文件。