我编写了一个 git commit hook 并在一个名为 的存储库中对其进行了测试myrepo
。我现在想将其复制到文件~/repos
夹中的所有存储库中。为此我尝试过:
$ cd ~/repos/myrepo/.git/hooks
$ cp prepare-commit-msg ~/repos/*/.git/hooks
当我运行此cp
错误时,每个目录上都会出现以下消息repos
:
cp: -r not specified; omitting directory <directory-name>
我 100% 确定prepare-commit-msg
这不是一个目录。为什么cp
抱怨我没有使用-r
?
答案1
find
可能就是您正在寻找的工具。您可以使用它来查找指定的hooks
并驻留在您的~/repos/
文件夹下的每个目录。对于找到的每个此类目录find
,您告诉它将文件复制到那里。
myrepo
当存储库尝试将文件复制到自身时,这将导致出现一条错误消息,但可以忽略该错误。
cd ~/repos/myrepo/.git/hooks
find ~/repos/ -type d -name hooks -exec cp -vp prepare-commit-msg {} \;
可以改进此命令以处理目录或文件名中奇数字符的情况,但这就是它的要点。
至于为什么你的原始cp
命令不起作用,可能有一个问题可以更好地解释它,但这是因为 shell 将你的命令扩展为:
cp prepare-commit-msg ~/repos/repo_A/.git/hooks ~/repos/repo_B/.git/hooks ~/repos/repo_C/.git/hooks ~/repos/repo_D/.git/hooks ~/repos/repo_E/.git/hooks
并给出该语法,cp
认为您希望它复制文件prepare-commit-msg
和四个目录~/repos/repo_A/.git/hooks
并将~/repos/repo_D/.git/hooks
所有复制的文件/目录放入~/repos/repo_E/.git/hooks
.当然,这不是您想要做的,但cp
告诉您除非您使用该-r
选项,否则它不会递归复制目录。
如果您想构建类似于原始语法的解决方案,您可以使用:
cd ~/repos/myrepo/.git/hooks
dirs=( ~/repos/*/.git/hooks )
for d in "${dirs[@]}"
do
cp -vp prepare-commit-msg "$d/"
done
答案2
你可以cp
用你自己的包装cp2dirs
:
function cp2dirs(){
from="$1";shift
[ -f "$from" ] && while (($#)); do cp "$from" "$1/"; shift; done
}
然后cp2dirs prepare-commit-msg ~/repos/*/.git/hooks
呢