153

If I have a working copy of a Subversion repository, is there a way to delete all unversioned or ignored files in that working copy with a single command or tool? Essentially, I'm looking for the SVN analogue to git clean.

Either a command line or GUI solution (for TortoiseSVN) would be acceptable.

Nick Meyer
  • 39,212
  • 14
  • 67
  • 75

12 Answers12

157

I know this is old but in case anyone else stumbles upon it, newer versions (1.9 or later) of svn support --remove-unversioned, e.g. svn cleanup . --remove-unversioned.

https://subversion.apache.org/docs/release-notes/1.9.html#svn-cleanup-options

gregpaton08
  • 383
  • 3
  • 7
Neil
  • 2,677
  • 1
  • 16
  • 9
  • 26
    For me, this is the right answer. It's a cross-platform command line answer. Also, you can remove ignored files with `svn cleanup . --remove-ignored` – Dan Atkinson May 16 '16 at 12:58
  • 1
    Works in svn 1.6 and up. – wegry Sep 09 '16 at 15:30
  • 3
    Please change that into 1.9, see also https://subversion.apache.org/docs/release-notes/1.9.html (I tried locally and it didn't work, and I'm on 1.8.8) – ikku100 Oct 11 '16 at 16:00
  • Tried it, on the v1.9.4 that came with TortoiseSVN, and the switch seemed to have no effect at all. – Nyerguds Nov 24 '16 at 10:03
  • 2
    Seems the problem is that it doesn't remove unversioned _folders_. – Nyerguds Nov 24 '16 at 10:19
  • 1
    @Nyerguds: True, this doesn't delete un-versioned folders, but only un-versioned files. Has anyone found a solution? – dhiraj suvarna Dec 21 '16 at 13:14
  • @phoenix I ended up writing a little c# command line tool that calls `svn status --depth=infinity -v --xml` and parses that to figure out which files to delete. Just had to be careful to ignore the .svn folder. – Nyerguds Dec 21 '16 at 14:05
  • This switch has just removed unversioned folders for me. – Kaerber Aug 14 '17 at 12:23
  • Since the question was how to remove unversioned *and* ignored files, the full answer is `svn cleanup --remove-unversioned --remove-ignored .` – haui Jul 03 '19 at 17:34
  • Just tried `svn cleanup --remove-ignored` in a working directory, and noticed that it (of course) deletes resources which are hidden from Subversion but I'd have rather liked to keep, e.g. directories of the virtualenv or of other SCM tools. For an `svn switch` to succeed, in most of my cases it would be sufficient to remove ignored files in subdirectories only ... – Tobias Oct 31 '19 at 10:25
143
svn status --no-ignore | grep '^[I?]' | cut -c 9- | while IFS= read -r f; do rm -rf "$f"; done

This has the following features:

  • Both ignored and untracked files are deleted
  • It works even if a file name contains whitespace (except for newline, but there's not much that can be done about that other than use the --xml option and parse the resulting xml output)
  • It works even if svn status prints other status characters before the file name (which it shouldn't because the files are not tracked, but just in case...)
  • It should work on any POSIX-compliant system

I use a shell script named svnclean that contains the following:

#!/bin/sh

# make sure this script exits with a non-zero return value if the
# current directory is not in a svn working directory
svn info >/dev/null || exit 1

svn status --no-ignore | grep '^[I?]' | cut -c 9- |
# setting IFS to the empty string ensures that any leading or
# trailing whitespace is not trimmed from the filename
while IFS= read -r f; do
    # tell the user which file is being deleted.  use printf
    # instead of echo because different implementations of echo do
    # different things if the arguments begin with hyphens or
    # contain backslashes; the behavior of printf is consistent
    printf '%s\n' "Deleting ${f}..."
    # if rm -rf can't delete the file, something is wrong so bail
    rm -rf "${f}" || exit 1
done
Richard Hansen
  • 51,690
  • 20
  • 90
  • 97
  • 2
    Exactly what I was looking for, works like a charm also on linux and MacOS! – rich Nov 29 '13 at 09:38
  • Do you need to reset the IFS? I chose not to make a 'svnclean' script. so I'm wondering if that will screw up IFS for the rest of the script... – C. Tewalt Apr 11 '14 at 21:51
  • 3
    @matrixugly: No, you don't need to change `IFS` back to what it was before. When you do `VARNAME=value command`, the assignment of `value` to `VARNAME` only applies during the execution of `command` (with some exceptions that don't apply to `read`). See [the POSIX specification](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09) and [this POSIX bug report](http://austingroupbugs.net/view.php?id=654#c1559) for more details. – Richard Hansen Apr 12 '14 at 05:27
  • @rich, thanks for sharing this. Came looking for an svn cleanup solution a few years back, and also walked away with some shell scripting knowledge! Evidently I've been coming back to this answer quite a bit. – C. Tewalt Jul 13 '16 at 14:37
  • watch out, this will also remove hidden directories like .idea which will flush your IntelliJ Idea configuration (including for example shelved changes..) – Line Dec 23 '21 at 11:01
104

Using TortoiseSVN:

oddRaven
  • 672
  • 1
  • 7
  • 20
Stefan
  • 43,293
  • 10
  • 75
  • 117
  • 7
    Nice feature! I had to read the link, though, to find out that it only works on the list view (not the tree view) on XP -- maybe you should include that in your answer. – Nick Meyer May 11 '10 at 20:40
  • 5
    Does the command line version of svn (specifically on windows) not provide the same function? – blong Mar 16 '12 at 13:06
  • 6
    As sombody pointed out below: `svn cleanup --remove-unversioned --remove-ignored .` – haui Jul 03 '19 at 17:35
43

This oneliner might help you:

$ svn status | grep '^?' | awk '{print $2}' | xargs rm -rf

Use with care!

jkramer
  • 15,440
  • 5
  • 47
  • 48
15

Modifying Yanal-Yves Fargialla and gimpf's answers using Powershell (but not being allowed to comment on the original post by Stackoverflow):

powershell -Command "&{(svn status --no-ignore) -match '^[\?i]' -replace '^.\s+' | rm -recurse -force}

This adds the carat ("^") to specify the start of line, avoiding matching all files that contain the letter "i". Also add the flags for -recurse and -force to rm to make this command non-interactive and so usable in a script.

gwilk
  • 159
  • 1
  • 3
  • The command needs an extra double quote at the end. I'd just add it, but edits have to be at least six characters apparently. – Ian Miller Feb 08 '17 at 15:52
8

Many things in SVN can be done in different ways, as evidenced by the varied command line answers given here. With the advent of version 1.7 there is yet another technique for TortoiseSVN that, in fact, provides a finer grain resolution than Stefan's answer provided, letting you select non-versioned files separately from ignored files. Just select TortoiseSvn >> Clean up... to open this dialog.

TortoiseSVN cleanup options

Michael Sorens
  • 35,361
  • 26
  • 116
  • 172
8

With powershell:

(svn status --no-ignore) -match '[?]' -replace '^.\s+' | rm

From command line:

powershell -Command "&{(svn status --no-ignore) -match '[?]' -replace '^.\s+' | rm}"
Yanal-Yves Fargialla
  • 1,257
  • 15
  • 16
  • 3
    I love this pure Windows script! I would recommend using `-match '[\?i]' -replace '^.{8}'` instead, which works correctly even if a filename _starts_ with a whitespace, and also deletes the ignored files. – gimpf Jul 25 '12 at 21:16
  • 1
    Using gimpf's suggested tweak works well, but I ran into a case where I encountered an ItemNotFoundException. Turns out, there was only a single file in the svn status result set. This tweak fixes that issue: `code` @(svn status --no-ignore) -match '[\?i]' -replace '^.{8}' | rm `. Figured it out with help from [this post](http://stackoverflow.com/questions/8651905/powershell-match-operator-returns-true-but-matches-is-null) – dirtybird Sep 11 '13 at 19:02
  • 1
    and because that will prompt you for directories not in svn (since recurse was not specified), it's no good for use in a script. Use: `powershell -Command "&{(svn status --no-ignore) -match '[\?i]' -replace '^.{8}' | remove-item -force -recurse}"` – thinkOfaNumber Oct 29 '14 at 08:40
6

This oneliner works for me (based on Richard Hansen's answer, which surprisingly didn't work for files containing spaces):

svn status --no-ignore | grep '^[I?]' | cut -c 9- | xargs -d"\n" -I{} rm {}
Dennis Golomazov
  • 16,269
  • 5
  • 73
  • 81
  • 2
    to delete unversioned folders too, add `-fr` to `rm` command: svn status --no-ignore | grep '^[I?]' | cut -c 9- | xargs -d"\n" -I{} rm -fr {} – Dennis Golomazov Jul 24 '12 at 07:29
5

Using TortoiseSVN:

  1. Right-Click on the root of the working copy and select TortoiseSVN -> "check for modifications"
  2. Select "Show ignored files"
  3. Sort by "Text status" column
  4. scroll to the "non-versioned" files, now all grouped together; select them all and right-click -> delete
  5. scroll to the "ignored" files, now all grouped together; select them all and right-click -> delete

Not really a nice and clean solution, but the fastest way I know of (on Windows).

Thanks to pkh for the tip with the ignored files.

Thomas Lötzer
  • 24,832
  • 16
  • 69
  • 55
  • I believe this will only remove non-versioned files. Ignored items won't be affected. – Dirk Vollmar May 10 '10 at 15:31
  • 2
    You don't need to use the commit dialogue, and you can get ignored files: Right-click | TortoiseSVN | Check for Modifications. Then you can click 'Show Ignored Files' and sort/delete appropriately. – pkh May 10 '10 at 15:38
4

Somebody said you can't do it from the Windows command line.

Bull.

for /f "tokens=2 delims= " %I IN ('svn st --no-ignore ^| findstr /R "^[I?]"') DO (DEL /S /F /Q /A:H "%I" & rmdir /S /Q "%I")

Does it in one line and doesn't require a single GNU tool. :)

ChokesMcGee
  • 166
  • 4
  • `for /f "tokens=2 delims= " %%I IN ('svn st --no-ignore ^| findstr /R "^[I?]"') DO (DEL /S /F /Q /A:H "%%I" & rmdir /S /Q "%%I")` – Darien Pardinas Nov 13 '15 at 00:16
  • @DarienPardinas, your version is especially useful if plugging into a Jenkins "Execute Windows batch command", which I just learned is not a command prompt but more like a batch script, therefore the need for `%%` over `%` – jxramos Jun 16 '16 at 21:08
4

This is similar to other answers, but actually gets ignored files (note the 'I' in the REs):

 rm -rf `svn status --no-ignore | grep '^[\?I]' | sed 's/^[\?I]//'`
pkh
  • 3,639
  • 1
  • 23
  • 18
1

you can't delete them with just SVN command line (not sure about GUI tools though) if you are under linux system this might help:

http://www.guyrutenberg.com/2008/01/18/delete-unversioned-files-under-svn/

The other (brutal) method is to commit changes, delete all from folder and checkout again.

Juriy
  • 5,009
  • 8
  • 37
  • 52