Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rsync exclude according to .gitignore & .hgignore & svn:ignore like --filter=:C

People also ask

Does rsync use Gitignore?

gitignore files happen to use a syntax compatible with rsync . @JesseGlick is right, rsync is not able to parse . gitignore files, see stackoverflow.com/a/50059607/99834 workround.

What should I exclude from rsync?

The --exclude-from rsync option allows us to specify a file that contains a list of directories to be excluded. The file should be plaintext, so a simple . txt file will do. List one directory per line as you're compiling the list of directories that you want to exclude.

Should .gitignore be ignored?

The . gitignore file's purpose is to prevent everyone who collaborates on a project from accidentally commiting some common files in a project, such as generated cache files. Therefore you should not ignore .

Where does the gitignore file go?

The . gitignore file tells Git which files to ignore when committing your project to the GitHub repository. gitignore is located in the root directory of your repo. / will ignore directories with the name.


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.


You can use git ls-files to build the list of files excluded by the repository's .gitignore files. https://git-scm.com/docs/git-ls-files

Options:

  • --exclude-standard Consider all .gitignore files.
  • -o Don't ignore unstaged changes.
  • -i Only output ignored files.
  • --directory Only output the directory path if the entire directory is ignored.

The only thing I left to ignore was .git.

rsync -azP --exclude=.git --exclude=`git -C <SRC> ls-files --exclude-standard -oi --directory` <SRC> <DEST>

After the hours of research I have found exactly what I need: to sync destination folder with the source folder (also deleting files in the destination if they were deleted in the source), and not to copy to the destination the files that are ignored by .gitignore, but also not to delete this files in the destination:

rsync -vhra /source/project/ /destination/project/ --include='**.gitignore' --exclude='/.git' --filter=':- .gitignore' --delete-after

Another words, this command completely ignore files from .gitignore, both in source and in the destination. You can omit --exclude='/.git' part if want to copy the .git folder too.

You MUST copy .gitignore files from the source. If you will use LordJavac's command, the .gitignore will not be copied. And if you create a file in the destination folder, that should be ignored by .gitignore, this file will be deleted despite .gitignore. This is because you don't have .gitignore-files in the destination. But if you will have this files, the files described in the .gitignore will not be deleted, they will be ignored, just expected.


how about rsync --exclude-from='path/.gitignore' --exclude-from='path/myignore.txt' source destination?
It worked for me.
I believe you can have more --exclude-from parameters too.


2018 solution confirmed

rsync -ah --delete 
    --include .git --exclude-from="$(git -C SRC ls-files \
        --exclude-standard -oi --directory >.git/ignores.tmp && \
        echo .git/ignores.tmp')" \
    SRC DST 

Details: --exclude-from is mandatory instead of --exclude because likely case that exclude list would not be parsed as an argument. Exclude from requires a file and cannot work with pipes.

Current solution saves the exclude file inside the .git folder in order to assure it will not affect git status while keeping it self contained. If you want you are welcome to use /tmp.


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


Try this:

rsync -azP --delete --filter=":- .gitignore" <SRC> <DEST>

It can copy all files to remote directory excluding files in '.gitignore', and delete files not in your current directory.