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.