Rsync includes a nifty option --cvs-exclude to “ignore files in the same way CVS does”, but CVS has been obsolete for years. Is there any way to make it also ex
Instead of creating exclude filters, you can use git ls-files to select each file to rsync:
#!/usr/bin/env bash
if [[ ! $# -eq 2 ]] ; then
echo "Usage: $(basename $0) <local source> <rsync destination>"
exit 1
fi
cd $1
versioned=$(git ls-files --exclude-standard)
rsync --verbose --links --times --relative --protect-args ${versioned} $2
This works even though git ls-files returns newline separated paths. Probably won't work if you have versioned files with spaces in the filenames.
Per the rsync man page, in addition to the standard list of file patterns:
files listed in a $HOME/.cvsignore are added to the list and any files listed in the CVSIGNORE environment variable
So, my $HOME/.cvsignore file looks like this:
.git/
.sass-cache/
to exclude .git and the files generated by Sass.
Alternatives:
git ls-files -zi --exclude-standard |rsync -0 --exclude-from=- ...
git ls-files -zi --exclude-per-directory=".gitignore" |...
(rsync only partly understands .gitignore)
For mercurial you might use
hg status -i | sed 's/^I //' > /tmp/tmpfile.txt
to collect the list of files which are NOT under mercurial control because of .hgignore restrictions and then run
rsync -avm --exclude-from=/tmp/tmpfile.txt --delete source_dir/ target_dir/
to rsync all files except the ignored ones. Notice -m flag in rsync that will exclude empty directories from syncing because hg status -i would only list excluded files, not dirs
As mentioned by luksan, you can do this with the --filter switch to rsync. I achieved this with --filter=':- .gitignore' (there's a space before ".gitignore") which tells rsync to do a directory merge with .gitignore files and have them exclude per git's rules. You may also want to add your global ignore file, if you have one. To make it easier to use, I created an alias to rsync which included the filter.
Check out the MERGE-FILES FILTER RULES section in rsync(1).
It looks like it's possible to create a rsync --filter rule that will include .gitignore files as traverses the directory structure.