Wednesday, August 22, 2007

Recursively Excluding Directories with Info-ZIP

You want to compress the content of a directory, ignoring all the .svn files created by Subversion (or the .cvs files from CVS). Info-ZIP unfortunately doesn't have a simple options to do that. So instead, here is what you can do:

find . -name .svn -exec echo {}/* \; > /tmp/exclude.txt; zip -q9r * -x@/tmp/exclude.txt

With find, you first output the path to all the .svn directories into a temporary file, adding "/*" at the end of the path. Then you pass that file to zip with the -x@ option.

This works just fine, but is there a better way, maybe without using a temporary file, with everything in one line?

Update November 1, 2007 - The following, suggested by Gavin in the comments of this post, works like a charm and fits on one line. Here we are compressing the content of a WEB-INF directory to create a WAR file:

find WEB-INF -path "*/.svn" -prune -o -print | xargs zip myapp.war

Update February 16, 2009 - Tastenmetzger suggested in the comment an even simpler way of achieving the same result, using just the zip command:

zip -r * -x *.DS_Store *.svn*

Isn't that beautiful?


Anonymous said...

Hi, I just needed to do the same thing, and came across your post. After some scouting of the online docs, I think this is the simplest way:

% find myproj -path "*/.svn" -prune -
o -print | xargs zip

cheers - Gavin

Alessandro Vernet said...


Very nice! Indeed, this is simpler that the solution I suggested, and does not require the use of a temporary file. Thanks for the tip!


Anonymous said...

Hi there,

why not trying it this way:
zip -r * -x .DS_Store *.svn*

The .DS_Store is a crappy metafile created on OS-X systems.



Alessandro Vernet said...


Yes, actually your suggestion is even simpler. There is just a * missing before .DS_Store, so all the .DS_Store in the subdirectories are ignored. I will add an update to the main post; thank you for the suggestion!