I'm using rsync
to copy some files from a share to another.
Recursively, I need to:
- Delete files at destination that were removed from the origin
- Only sync
.php
and.js
files - Exclude every other file type
- Do not delete
.svn/
directories at destination
If I use this:
rsync -zavC --delete --include='*.php' --include='*.js' --exclude="*" \
/origin /destination
Then rsync
is not recursive because exclude="*"
excludes all files but also folders.
If I add --include="*/"
then the .svn/
directory gets deleted (it also gets included).
How can I solve this mind blasting dilemma?
uname -a
:
Linux tux 3.9.2-1-ARCH #1 SMP PREEMPT Sat May 11 20:31:08 CEST 2013
x86_64 GNU/Linux
rsync
version:
rsync 3.0.9-6
Best Answer
1st attempt (didn't work)
You need to include the directories in addition to the files:
2nd attempt
test data
I wrote this script to create some sample data to test this out on. Here's that script,
setup_svn_sample.bash
:Running it produces the following directories:
source dir
destination dir
Running the above
rsync
command:Resulting dir2 afterards:
Why does it work?
The key piece to this script is to make use of the filters capability of
rsync
. Filters allow you to remove files from the matched set at various points in the command. So in our case we're filtering any files that match the pattern*/.svn*
. The modifiers-rs_
tell the filter that we want to filter on both the source side as well as the target side.excerpt from the FILTER NOTES section of rsync's man page
See man rsync for more details.
Tips for figuring this out (hint using
--dry-run
)While describing how to do this I thought I'd mention the
--dry-run
switch torsync
. It' extremely useful in seeing what will happen without having thersync
actually take place.For Example
Using the following command will do a test run and show us the decision logic behind
rsync
:In the above output you can see that the
./svn
directories are being protected by our filter rule. Valuable insight for debugging thersync
.References