有时我需要执行以下命令
cp -rv demo demo_bkp
但是我想忽略目录.git中的所有文件。我如何实现这一目标?复制.git文件需要很长时间,我不需要这些文件。
答案 0 :(得分:83)
要特别忽略git目录,我首先try git export
。
但一般来说,要复制不包含某些文件或文件夹的目录树,我建议您使用rsync
而不是cp
。语法大致相同,但rsync
有方式更多选项,包括一个用于排除所选文件的选项:
rsync -rv --exclude=.git demo demo_bkp
参见例如the man page了解更多信息。
答案 1 :(得分:8)
行。振作起来。这不太好。
find demo -depth -name .git -prune -o -print0 | cpio -0pdv --quiet demo_bkp
这里发生了什么?
find demo | cpio -p demo_bkp
找到符合您想要的任何条件的文件,并使用cpio复制它们(所谓的“传递”模式)。
find -depth
更改了打印文件的顺序,以匹配cpio想要的顺序。
find -name .git -prune
告诉我不要递归.git
个目录。
find -print0 | cpio -0
已找到使用NUL字符(\0
)来分隔文件名。如果有任何带有空格,换行符或其他异常字符的奇怪命名文件,这是为了获得最大的稳健性。
cpio -d
根据需要创建目录。
cpio -v --quiet
打印每个文件名,同时省略“X blocks copies”消息,cpio通常会在最后打印。
答案 2 :(得分:3)
继续沿用rsync
的想法,如果您有太多要忽略的文件模式,则可以使用--exclude-from=FILE
选项。
--exclude-from=FILE
选项采用文件[FILE
],该文件包含排除模式(每行一个模式),并排除所有与模式匹配的文件。
因此,假设您要将目录demo
复制到demo_bkp
,但是您想忽略具有以下模式的文件-.env
,.git
,{{1} },coverage
。您可以创建一个名为node_modules
的文件,并将样式逐行添加到.copyignore
:
.copyignore
然后运行:
.env
.git
coverage
node_modules
就是这样。 rsync -rv --exclude-from=./.copyignore demo demo_bkp
将被复制到demo
中,而所有与demo_bkp
中指定的模式匹配的文件都将被忽略。
答案 3 :(得分:2)
我认为这会解决问题:
cd demo
find . -not -path \*/.\* -type d -exec mkdir -p -- ../demo_bkp/{} \;
find . -not -path \*/.\* -type f -exec cp -- {} ../demo_bkp/{} \;
首先查找并创建每个目录。然后查找并复制每个文件。
请注意,它不适用于特殊文件(符号链接等)。
答案 4 :(得分:0)
简单的解决方案,可能是最好的运行时,符合 OP(谁想使用 cp
):
touch /path/to/target/.git
cp -n -ax * /path/to/target/
rm /path/to/target/.git
这利用了 -n
的 cp
选项,强制 cp
不覆盖现有目标。
缺点:适用于 GNU cp
。如果您没有 GNU cp
,那么 cp
操作可能会返回错误代码 (1
),这很烦人,因为您无法判断它是否是真正的失败.