Rsync包含一个漂亮的选项--cvs-exclude
,以“以与CVS相同的方式忽略文件”,但CVS已经过时多年。有没有办法让它也排除现代版本控制系统(Git,Mercurial,Subversion)会忽略的文件?
例如,我从GitHub检出了很多Maven项目。通常,它们包含.gitignore
列表,至少target
,默认的Maven构建目录(可能出现在顶层或子模块中)。由于这些目录的内容完全是一次性的,并且它们可能远远大于源代码,因此我想在使用rsync进行备份时排除它们。
当然我可以明确地--exclude=target/
,但这会意外地压制恰好恰好名为target
的不相关目录,并且不应该被忽略。
我可以提供磁盘上任何.gitignore
,.hgignore
或svn:ignore
属性中提到的所有文件名和模式的绝对路径的完整列表,但这将是一个必须由某种脚本生成的巨大列表。
由于rsync没有内置支持除CVS之外的VCS检出,是否有任何好的技巧可以为它们提供忽略模式?或某种回调系统,可以询问用户脚本是否应该包含给定的文件/目录?
更新:--filter=':- .gitignore'
正如LordJavac所建议的那样对于Git来说似乎也适用于--filter=:C
对CVS,至少在我发现的例子中,尽管它是不清楚语法是否完全匹配。 --filter=':- .hgignore'
对Mercurial不起作用;例如包含.hgignore
之类的行^target$
(Git /target/
的Mercurial等价物)不会被rsync识别为正则表达式。对于Subversion来说似乎没什么用处,因为你需要为{1.6}或更早的工作副本解析.svn/dir-prop-base
,并为1.7或更高版本的工作副本沮丧地举手。
答案 0 :(得分:94)
正如luksan所述,您可以使用--filter
切换到rsync
来执行此操作。我用--filter=':- .gitignore'
(在.gitignore之前有一个空格)来实现这一点,它告诉rsync
与.gitignore
文件进行目录合并,并根据git的规则排除它们。您可能还想添加全局忽略文件(如果有)。为了更容易使用,我创建了一个包含过滤器的rsync
别名。
答案 1 :(得分:8)
您可以使用git ls-files
构建存储库.gitignore
文件排除的文件列表。
https://git-scm.com/docs/git-ls-files
选项:
--exclude-standard
考虑所有.gitignore
个文件。-o
不要忽略未分级的更改。-i
仅输出被忽略的文件。--directory
仅在忽略整个目录时输出目录路径。我唯一要忽略的是.git
。
rsync -azP --exclude=.git --exclude=`git -C <SRC> ls-files --exclude-standard -oi --directory` <SRC> <DEST>
答案 2 :(得分:5)
rsync --exclude-from='path/.gitignore' --exclude-from='path/myignore.txt' source destination
怎么样?
它对我有用。
我相信你也可以拥有更多的--exclude-from
参数。
答案 3 :(得分:4)
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
详细信息:--exclude-from
是强制性的,而不是--exclude,因为排除列表的可能情况不会被解析为参数。从需要文件中排除,不能使用管道。
当前解决方案将排除文件保存在.git文件夹中,以确保它在保持自包含状态时不会影响git status
。如果您愿意,欢迎您使用/ tmp。
答案 4 :(得分:3)
经过数小时的研究,我确切地找到了我所需要的:将目标文件夹与源文件夹同步(如果在源中删除了文件,也要删除目标中的文件),而不是将目标文件复制到目标被.gitignore忽略,但也不会在目标位置删除此文件:
rsync -vhra /source/project/ /destination/project/ --include='**.gitignore' --exclude='/.git' --filter=':- .gitignore' --delete-after
换句话说,此命令完全忽略源和目标中的.gitignore文件。
如果也要复制--exclude='/.git'
文件夹,则可以省略.git
部分。
您必须从源复制.gitignore文件。如果使用LordJavac的命令,则不会复制.gitignore。 而且,如果您在目标文件夹中创建一个文件,则.gitignore应该忽略该文件,尽管.gitignore也会删除该文件。 这是因为目标中没有.gitignore文件。 但是,如果您有此文件,则.gitignore中描述的文件将不会被删除,只会被忽略。
答案 5 :(得分:2)
对于 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
答案 6 :(得分:2)
尝试一下:
rsync -azP --delete --filter=":- .gitignore" <SRC> <DEST>
它可以将所有文件复制到远程目录(“ .gitignore”中的文件除外),并删除不在当前目录中的文件。
答案 7 :(得分:1)
我有一些非常大的.gitignore
文件,而且没有#34;纯rsync&#34;解决方案对我有用。我写了这个rsync wrapper script,它完全尊重.gitignore
规则(包括!
- 样式异常和子目录中的.gitignore
文件),并且对我来说就像一个魅力。
答案 8 :(得分:0)
查看rsync(1)中的MERGE-FILES FILTER RULES部分。
看起来可以创建一个rsync --filter规则,其中包含.gitignore文件遍历目录结构。
答案 9 :(得分:0)
除了rsync
手册页之外,还有标准的文件模式列表:
$ HOME / .cvsignore中列出的文件将添加到列表中,并且CVSIGNORE环境变量中列出的所有文件
因此,我的$ HOME / .cvsignore文件如下所示:
.git/
.sass-cache/
排除.git和Sass生成的文件。
答案 10 :(得分:0)
您可以使用git ls-files
选择每个文件到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
即使git ls-files
返回换行符分隔的路径,这仍然有效。如果您在文件名中包含带空格的版本文件,则可能无法工作。
答案 11 :(得分:0)
替代品:
git ls-files -zi --exclude-standard |rsync -0 --exclude-from=- ...
git ls-files -zi --exclude-per-directory=".gitignore" |...
(rsync仅部分理解.gitignore)
答案 12 :(得分:0)
简短回答
@Override
public void onNewIntent (Intent intent) {
setIntent(intent);
}
@Override
public void onResume() {
super.onResume();
Bundle extras = getIntent().getExtras();
Log.e(APP_TAG, "EXTRAS FROM RESUME: "+extras);
if (extras != null && extras.getString("accountID") != null) {
String accountParam = "";
Log.e(APP_TAG, "AccountID in onResume: "+extras.getString("accountID"));
accountParam = "?accountID="+extras.getString("accountID");
loadUrl("file:///android_asset/www/index.html"+accountParam);
}
}
参数含义:
rsync -r --info=progress2 --filter=':- .gitignore' SOURCE DEST/
:递归
-r
:显示进度
--info=...
:排除.gitignore文件上列出的规则