views:

2137

answers:

11

Hi,

does anybody know a way to recursively remove all files in a working copy that are not under version control? (I need this to get more reliable results in my automatic build VMware.)

Thanks, Stefan

+4  A: 

Can you not just do an export to a new location and build from there?

leppie
For an automated build I would want a clean export.
g .
+5  A: 

I use this python script to do that:

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

It seems to do the job pretty well.

Thomas Watnedal
Thank you! Will be no problem to convert that to C#.
Stefan Schultze
+6  A: 

this works for me in bash:

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

The -i on the rm lets you confirm every delete.

Ken
Also usable in Windows in cygwin.
Honza
Is it safe to "share" and manipulate a SVN working copy between the Windows and CygWin builds of svn?
Craig McQueen
Actually I guess this example is not manipulating the working copy. Just doing status.
Craig McQueen
@Craig - all this is doing is finding all the files in the working copy that haven't been added (by checking for a ? status) and deleting them. Exactly the same as doing a status and then manually deleting the files.
Ken
The **svn status** command should probably use the **--no-ignore** option. Then the **egrep** command should also check for **"I"** status character.
Craig McQueen
+1  A: 

My C# conversion of Thomas Watnedals Python script:

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();
 }
}
Stefan Schultze
I would rather move the unversioned files, just in case you need them somewhere later.
leppie
On a development machine, of course - but in the build VMware, that wouldn't make any sense cause nobody logs on to it and creates files.
Stefan Schultze
Thanks, I used this as part of my MSBuild script in cruisecontrol to clean up my source dir prior to builds
gregmac
A: 

I couldn't get any of the above to work without additional dependencies I didn't want to have to add to my automated build system on win32. So I put together the following Ant commands - note these require the Ant-contrib JAR to be installed in (I was using version 1.0b3, the latest, with Ant 1.7.0).

Note this deletes all unversioned files without warning.

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

For a different folder, change the ${basedir} reference.

Note: only deletes unversioned files; does not remove empty unversioned folders.
+9  A: 

I ran across this page while looking to do the same thing, though not for an automated build.

After a bit more looking I discovered the 'Extended Context Menu' in TortoiseSVN. Hold down the shift key and right click on the working copy. There are now additional options under the TortoiseSVN menu including 'Delete unversioned items...'.

Though perhaps not applicable for this specific question (i.e. within the context of an automated build), I thought it might be helpful for others looking to do the same thing.

g .
Wow, brilliant!
eddiegroves
Great! On XP it only works in the list view (right side of explorer) not in the tree view (left side).
Christopher Oezbek
A: 

For the people that like to do this with perl instead of python, Unix shell, java, etc. Hereby a small perl script that does the jib as well.

Note: This also removes all unversioned directories

#!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();
+1  A: 

If you are on windows command line,

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

Sukesh Nambiar
This kinda worked for me. Seemed to choke on some unversioned folders though.
jpierson
+1  A: 

See: svn-clean

Martin Burger
A: 

If you are using tortoise svn there is a hidden command to do this. Hold shift whilst right clicking on a folder to launch the context menu in windows explorer. You will get a "Delete Unversioned Items" command.

see the bottom of this page for details http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-rename.html

rob bentley