rsync根据.gitignore&.hgignore&svn排除:忽略像–filter =:C
Rsync包含一个漂亮的选项--cvs-exclude
来“以与CVS相同的方式忽略文件”,但CVS已经过时了多年。 有没有办法让它排除现代版本控制系统(Git,Mercurial,Subversion)会忽略的文件?
例如,我有很多从GitHub签出的Maven项目。 通常他们包括一个.gitignore
,至less列出target
,默认的Maven构build目录(可能出现在顶层或子模块中)。 由于这些目录的内容完全是一次性的,而且可以远远大于源代码,所以在使用rsync进行备份时,我想排除它们。
当然,我可以明确地说--exclude=target/
但是这会意外地压制那些恰好被命名为target
并且不应该被忽略的不相关的目录。
我可以为我的磁盘上的任何.gitignore
, .hgignore
或svn:ignore
属性提供的所有文件名和模式的绝对path的完整列表,但这将是一个巨大的列表,必须由某种的脚本。
由于rsync没有内置的CVS以外的VCS检出支持,有没有什么好的方法可以把它们的忽略模式提供给它? 或者某种callback系统,用户脚本可以被询问是否应该包含给定的文件/目录?
更新 :– --filter=':- .gitignore'
build议的--filter=':- .gitignore'
似乎也适用于Git --filter=:C
对于CVS至less在我已经find的例子上做了,尽pipe目前还不清楚语法是完全匹配的。 --filter=':- .hgignore'
对Mercurial来说不是很好; 例如,一个包含像^target$
(Git /target/
的Mercurial等价物)这样的行的.hgignore
不能被rsync识别为正则expression式。 而且什么似乎都没有为Subversion工作,你将不得不parsing.svn/dir-prop-base
为1.6或更早版本的工作副本,并为1.7或更高版本的工作副本惊慌失措。
正如luksan所提到的,你可以用--filter
切换到rsync
。 我用--filter=':- .gitignore'
(在“.gitignore”之前有一个空格)来实现这一点,它告诉rsync
与.gitignore
文件进行目录合并,并且按照git的规则排除它们。 如果您有全局忽略文件,您可能还想添加您的全局忽略文件。 为了使它更容易使用,我创build了一个rsync
的别名,其中包括filter。
rsync --exclude-from='path/.gitignore' --exclude-from='path/myignore.txt' source destination
?
它为我工作。
我相信你可以有更多的--exclude-from
参数。
你可以使用git ls-files
来build立被存储库的.gitignore
文件排除的文件列表。 https://git-scm.com/docs/git-ls-files
选项:
-
--exclude-standard
考虑所有.gitignore
文件。 -
-o
不要忽略未分离的更改。 -
-i
只输出忽略的文件。 -
--directory
如果整个目录被忽略,只输出目录path。
我唯一不理的就是.git
。
rsync -azP --exclude=.git --exclude=`git -C <SRC> ls-files --exclude-standard -oi --directory` <SRC> <DEST>
我有一些非常大的.gitignore
文件,没有一个“纯粹的rsync”解决scheme为我工作。 我写了这个rsync包装器脚本 ,它完全尊重.gitignore
规则(在子目录中包括!
样式的exception和.gitignore
文件),并为我工作的魅力。
为了mercurial,你可以使用
hg status -i | sed 's/^I //' > /tmp/tmpfile.txt
收集由于.hgignore限制而不属于mercurial控制的文件列表,然后运行
rsync -avm --exclude-from=/tmp/tmpfile.txt --delete source_dir/ target_dir/
rsync除了忽略的所有文件。 注意rsync中的-m标志将排除空目录同步,因为hg status -i只会列出排除的文件,而不是dirs
查看rsync(1)中的MERGE-FILES FILTER RULES部分。
看起来可以创build一个rsync –filter规则,该规则将包含.gitignore文件作为遍历目录结构。
根据rsync
手册页,除了文件模式的标准列表之外:
列在$ HOME / .cvsignore中的文件将被添加到列表以及CVSIGNORE环境variables中列出的任何文件
所以,我的$ HOME / .cvsignore文件如下所示:
.git/ .sass-cache/
排除.git和Sass生成的文件。
您可以使用git ls-files
来select每个rsync git ls-files
,而不是创build排除筛选器:
#!/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
这工作,即使git ls-files
返回换行分隔的path。 如果您的文件名中包含空格的文件版本可能不会工作。