简而言之
要 rsync 一个已排除 .git/ 但仍保留 .git/config 文件的文件夹,该怎么做?
我的谷歌搜索没有帮助所以我在这里问。
详细信息
我想将我的所有项目代码的快照保存到另一台机器上 - 以后我可能没有 git repo 访问权限。
每个项目代码文件夹都是 git 克隆的,因此它们都有 .git 文件夹。
我不需要那些.git,所以将它们排除在外。
但是我需要知道项目来自哪个 git repo,所以需要保留 .git/config。
我尝试过但没有奏效的方法运行
rsync -chazvP --dry-run --exclude=".git" --include=".git/config" $FROM/ $TO/
# . . . . .
如果您知道正确的方法,请分享。
答案1
包括要保留的文件,然后排除不想要的文件。.git/
但是,您不能排除目录本身,因为这样就没有匹配项了.git/config
。
rsync --dry-run -av --include '.git/config' --exclude '.git/*' "$FROM/" "$TO/"
与往常一样,先测试一下,然后--dry-run
在你觉得合适时删除。记得用双引号括住你的变量,以保护它们免受 shell 的字扩展的影响。
作为参考,这在文档(man rsync
)中有所描述,但我会首先说,除非你已经理解它,否则很难理解......
例如,要包含“/foo/bar/baz”,就不能排除目录“/foo”和“/foo/bar”。排除其中一个父目录会阻止检查其内容,从而切断 rsync 对这些路径的递归,并使“/foo/bar/baz”的包含无效(因为 rsync 无法匹配它在目录层次结构的截止部分中从未见过的内容)。
使用尾随“*”规则时,概念路径排除尤其重要。例如,这将不起作用:
+ /some/path/this-file-will-not-be-found + /file-is-included - *
这会失败,因为父目录“some”被‘*’规则排除,所以 rsync 永远不会访问“some”或“some/path”目录中的任何文件。[...]另一种解决方案是为所有需要访问的父目录添加特定的包含规则。
答案2
根据您的评论:
我的 X 是“将我的所有项目代码快照保存到另一台机器上”
我建议只使用 git。它在内部将代码跟踪为目录快照,因此您可以获得 rsync 所做的一切 + git 的优点。
Git 可以通过 SSH、HTTP 甚至挂载的文件系统访问其他存储库。由于 rsync 是您选择的工具,我假设您已经设置了 SSH。如果您需要更新某些特定内容以使 git 正常工作,这是指南。
一旦你在第二台机器上克隆了你的 repo,git fetch --all
将仅使用自上次获取以来更新的文件来有效地更新你的 repo 的本地克隆。
或者,您可以git init --bare
在第二台机器上创建新的仓库,并将其作为远程仓库添加到第一台机器上。在这种情况下,您可以git push --all
在机器 1 上执行以更新机器 2。
或者,您可以使两个 repos 互相远程化,这样您就可以在两端启动更新。
为什么 git 是完美的解决方案?
- 你已经使用过 git,因此不需要再引入一个你不熟悉的工具
- 避免重新发明轮子
- 你不需要
.git/config
在脑子里解析,git remote get-url origin
它会告诉你仓库的来源 - Git 压缩并删除重复文件
- 保留分支和提交历史
- 仅传输更改,而不是整个快照