2008-10-27 38 views
102

有沒有人知道一種方式來遞歸刪除工作副本中所有不受版本控制的文件? (我需要這樣才能在自動構建VMware中獲得更可靠的結果。)自動刪除Subversion未版本控制的文件

+7

我是一名SVN用戶,一直在比較Git和SVN,看看我是否最終想做這個開關。看起來這可能是Git使用其「git clean」命令閃耀的另一個示例。 – jpierson 2010-09-21 14:11:55

+3

或Mercurial中的[`hg purge --all`](http://mercurial.selenic.com/wiki/PurgeExtension)。 – 2012-03-06 17:58:16

回答

18

我用這個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)) 

似乎做的工作相當不錯。

+0

在Windows上無法使用Python 2.6 – 2014-05-05 15:07:24

+1

仍然適用於Python 2.7.2。 Warren P:你能提供更多細節嗎? – 2014-06-23 10:42:10

+0

我認爲這只是Python 2.6的一個問題。在2.7中再次爲我工作。 – 2014-06-23 14:12:16

4

您不僅可以導出到新位置並從那裏創建嗎?

+1

對於自動構建,我想要一個乾淨的導出。 – 2009-06-30 14:52:55

+1

理想情況下,您可以這樣做,但如果您的結帳量非常大,則會出現問題。這可能是OP問道:縮短構建的原因。 – jpmc26 2014-03-31 23:06:42

132

這個工作對我來說在bash:

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

Seth Reno的更好:

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

它處理的文件名

按照下面的評論未版本控制的文件夾和空間,這只是適用於顛覆者不知道的文件(status =?)。任何顛覆確實知道(包括忽略的文件/文件夾)不會被刪除。

如果你使用Subversion 1.9或更高版本,你可以簡單地使用與--remove-未版本控制和--remove忽視的選項

+6

也可以在cygwin的Windows中使用。 – Honza 2009-05-04 16:56:56

+0

在Windows和CygWin版本的svn之間「共享」和操作SVN工作副本是否安全? – 2009-06-30 01:39:12

+0

其實我猜這個例子不是在操縱工作副本。只是在做狀態。 – 2009-06-30 01:40:02

3

托馬斯Watnedals Python腳本的我的C#轉換svn cleanup命令:

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(); 
    } 
} 
2

我無法得到任何上述工作,沒有額外的依賴關係我不想在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}參考。

71

我跑過這個頁面,同時尋找做同樣的事情,但不適用於自動構建。

經過一番多看後,我在TortoiseSVN中發現'擴展上下文菜單'。按住shift鍵並右鍵單擊工作副本。現在TortoiseSVN菜單下還有其他選項,包括'刪除未版本控制的項目...'。

雖然也許不適用於這個特定的問題(即在自動構建的情況下),但我認爲這對於那些希望做同樣事情的人可能會有所幫助。

0

對於那些喜歡用perl而不是python,Unix shell,java等來做這件事的人來說。這裏有一個小的perl腳本來完成jib的工作。

注:這也會刪除所有未版本控制目錄

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

如果您使用的是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" 

如果您在使用本批文件需要加倍%

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

如果您正在使用烏龜SVN有一個隱藏的命令來做到這一點。按住Shift鍵同時右鍵單擊文件夾以在Windows資源管理器中啓動上下文菜單。你會得到一個「刪除未版本化的項目」命令。

看到這個page對細節的底部,或者下面的屏幕截圖這凸顯與綠星的擴展功能,並與黃色矩形感興趣的一個...

SVN Extended context menu vs standard menu

0

如果你不想寫任何代碼,從svn2svn svn2.exe這樣做,也有an article它如何實現。刪除的文件夾和文件被放入回收站。

運行「svn2.exe sync [path]」。

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

刪除回聲,如果這是確定你想要做什麼。

5

Linux命令行:

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

或者,如果您的某些文件歸根所有:

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

這是基於肯的答案。 (肯的答案跳過忽略的文件;我的答案刪除它們)。

7

我將此添加到我的Windows PowerShell配置文件

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

還不如促進另一種選擇

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

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

而且可能是添加一個好主意--no-忽視的svn命令

1

純粹的Windows命令/蝙蝠的解決方案:

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

因爲大家都在做...

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

只要在unix-shell上做:

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

一個乾淨的方式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() 
1

我試過Seth Reno's版本從this answer但它並沒有爲我工作。在文件名前有8個字符,在cut -c9-中沒有9個字符。

所以這是我的版本的sed代替cut

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

我用〜3小時產生這一點。在Unix中需要5分鐘。 主要問題是:Win文件夾名稱中的空格,無法編輯%% i以及在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! 
) 
3
svn st --no-ignore | grep '^[?I]' | sed 's/^[?I] *//' | xargs -r -d '\n' rm -r 

這是一個UNIX shell命令刪除不顛覆控制下的所有文件。

注:

  • svn stststatus一個內置的別名,即命令等同於svn status
  • --no-ignore還包括在狀態輸出非存儲庫文件,通過以其它方式將忽略像.cvsignore等機制 - 因爲目標是有一個乾淨的起點建立這個開關是必須的
  • grep過濾器的輸出,使只有文件未知到subversio n的左 - 與?名單開始行的文件未知的顛覆。如果沒有這一--no-ignore選項
  • 前綴到文件名通過sed
  • xargs命令通過-r指示無法執行rm除去可以忽略,當參數列表是空的
  • -d '\n'選項告訴xargs使用換行分隔符爲這樣的命令也適用於帶有空格
  • rm -r文件名的情況下,完整的目錄被使用(即不的一部分存儲庫)需要被刪除
0

上面的C#代碼snipet沒有爲我工作 - 我有烏龜svn客戶端,線格式稍有不同。這裏是與上面相同的代碼snipet,只是重寫爲函數和使用正則表達式。

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

如果你很酷使用PowerShell:

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

取出-WhatIf標誌,使指令實際執行刪除操作。否則,它將只輸出如果沒有-WhatIf而運行。

0

有關誰想要避免使用除了非標準MS-DOS的任何工具窗口這裏的人們命令的解決方案:

FOR/F 「令牌= 1 * delims =」 %G IN('SVN ST^| ('svn st^| findstr'^?'')DO rd/s/q「%H」

FOR/F「標記= 1 * delims =」%G IN/S/F/q 「%H」

  • SVN ST將顯示每個文件的工作副本
  • FINDSTR意願升的狀態和文件夾對於以'?'開頭的每一行,這意味着文件/文件夾未版本化
  • FOR將用作分隔符並在第一個(第一個是%G,其餘爲%H)之後使用標記 我們正在從svn st命令輸出中提取文件/文件夾。
  • rd會刪除文件夾,del會刪除文件。
3

如果你有你的路徑上TortoiseSVN,你在正確的目錄:

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

的選項在TortoiseSVN的幫助/command:cleanup描述:

使用/ NOUI防止彈出 的結果對話框,告訴清理完成或顯示錯誤消息 )。/noprogressui也會禁用進度對話框。/nodlg 禁用顯示清理對話框,其中用戶可以選擇清理時應該完成的工作。可用的操作可以是 ,這些操作可以通過狀態清理,/還原, /刪除版本,/撤銷,/ refreshshell和/ externals的選項/清理指定。

0

我會添加此作爲Thomas Watnedal's answer的評論,但還不能。

它的一個小問題(不會影響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: 
     print "Removing " + match.group(1) 
     removeall(match.group(1)) 

,以便它顯示它是什麼去除是有用的。

根據使用情況,正則表達式的?[\?ID]部分可能會更好,因爲D還會刪除受版本控制的已刪除文件。我想用它來建立一個乾淨的,簽入文件夾,所以在D狀態下應該沒有文件。

0

我還發現並使用了以下內容: svn status --no-ignore | awk'/ ^?/ {print $ 2}'| xargs rm

相關問題