Copy all files and folders excluding subversion files and folders on OS X

I'm trying to copy all files and folders from one directory to another, but exclude certain files. Specifically, I want to exclude subversion files and folders. However, I'd like a general yet concise solution.

I imagine I'll find the need to exclude several types of files in the near future. For example, I might want to exclude .svn, *.bak, and *.prj.

Here is what I've put together so for, but it is not working for me. The first part, find works, but I'm doing something wrong with xargs and cp. I tried cp with and without the -R. Also, I'm using OS X and it appears to have a less featured version of xargs than linux systems.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory

Solution 1:

(Edited after re-reading the question. Questioner says rsync is not installed)

A possible problem with your find/xargs solution is spaces in the filenames. To get around that, tell find and xargs to use a null character (ASCII 0) to separate the found files:

find ./sourcedirectory -not ( -name .svn -a -prune ) -print0 | xargs -0 -IFILES cp FILES ./destinationdirectory

If you find that rsync is available, I still think that rsync is the far better solution:

Use rsync with the -C option. From the rsync man page:

This is a useful shorthand for excluding a broad range of files that you often don't want to transfer between systems. It uses a similar algorithm to CVS to determine if a file should be ignored.

This will tell rsync to ignore these patterns:

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~
#* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj 
*.so *.exe *.Z *.elc *.ln core .svn/ .git/ .bzr/

For example:

rsync -avC /path/to/source/directory /path/to/destination/directory

(note: If you're not too familiar with rsync yet, be sure to read on that man page about how rsync deals with a trailing slash in the source path. It behaves differently if you include the slash than if you don't. Search for 'trailing slash')

Solution 2:

Not a general solutions but... you can use the svn export command to create a copy of the workspace without the .svn metadata folders.

Solution 3:

%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

if you want you can even put 'pv' or something similar in between the 2 tar processes.

Solution 4:

A dirty but quick and concise way:

cp -r source destination
find destination -iname .svn |xargs rm -rf

This copies one directory to another (thus the recursive option -r) and then recursively wipes out anything named .svn (ignoring case).

Solution 5:

I would go about it a different way, using tar and its exclude mechanism.

From in the destination directory:

tar -X excludefile -C source -f - . | tar xf -

This will cd to source, tar up the contents, excluding what is listed in excludefile, and then untar it to the current directory.