Sunday, 23 January 2011

Throw out the trash: clean up a Subversion working copy

Often times, one acquires a plethora of debris, detritus, flotsam and jetsam in one's SVN working copy. Mostly these are the standard build artefacts like .o files, but depending on the project it could be a variety of different things, like perhaps the forgotten remnants of silly little experiments.

One is really not very interested in being reminded of the existence of this digital rubble in the output of svn status. Therefore, there are various ways of telling Subversion to “ignore” certain files based on the pattern of their name.

That takes care of the output of svn status, but not of ls (which is still cluttered), nor your disk space. So what's a quick way of getting rid of those files?

It's easy:
svn status | grep ^? | awk '{print $2}' | xargs rm -rf
or, if you wish to also delete those files which are ignored by Subversion,
svn status --no-ignore | grep ^[?I] | awk '{print $2}' | xargs rm -rf
Note that this second version could be useful if make clean (or equivalent) is not quite as thorough as you'd like it to be.

And that's really all there is to it. But just because I like to make things complicated, I've wrapped up this idea in a little script – svnclean:

$ svnclean --help
usage: /home/carlo/bin/svnclean [-i] [-f] [-q] [-h|-?|--help]

Recursively cleans the current svn working copy starting from the current
directory.  It does this by inspecting the output of `svn status'.  Options:

    -i  Also remove files ignored by SVN (e.g. via svn:ignore properties)
    -f  Do not confirm deletion
    -q  Do not list every file before deletion, only print number of affected

    -h, -?, --help  This help

$ svnclean -i
Files/directories to be deleted:
Continue? [yn] 


  1. There is an svn-clean perl script available in the svn repository. It does most of the above (although I don't know how it handles svn:ignore) and it allows you to pass regex patterns of files to exclude from deletion.

  2. I suggest amending this slightly as follows so it works even on paths that have spaces in them;

    svn status --no-ignore | grep '^[?I]' | cut -c 9- | tr '\n' '\0' | xargs -0 rm -rf