我希望能够在将文件推送到第一个存储库时自动(可能使用钩子和/或GitHub API)将其提交和推送到第二个存储库。
第二个存储库不是第一个存储库的克隆,它们的文件夹布局不一定相同,只是有一堆共同的文件。
最简单的做法是什么?
如果我不需要安装http服务器或学习Perl,那就更好了 :)
让源代码库(在GitHub上)为 S1
,S2
...,文件集为F1
,F2
... 不重叠,以镜像的方式发送到一个目标存储库T
(也在GitHub上),其中相应的文件被视为只读。你的要求很特殊,因为Sn
和T
听起来并不是从彼此克隆而来,它们甚至可能没有任何共同的提交,这种情况下就不是推送/拉取场景。你也没有保证源文件更新是每个提交一次,甚至可能与非复制更改分组但隔离,因此这不涉及挑选提交。
S1
、S2
等,而不是在任何开发者克隆这些仓库时提交,因此客户端钩子无法帮助(并且可能难以维护)。当然,GitHub 不允许通用钩子,因此 Webhooks 是您最好的解决方案。您可以考虑另一个轮询克隆,它定期从 S1
... 拉取,执行逻辑,然后提交到 T,但与 Webhooks 相比,这听起来很棘手,Webhooks 将为您提供可靠的交付、重播能力、良好的审计跟踪等。X-Hub-Signature
验证并为所有Webhooks事件提供简单的事件监听器钩子。您可以为每个S设置一个端点,或者将它们分散开来更容易管理。Sn
映射到Fn
。X-GitHub-Event:push
的处理程序,并检查repository/name
和commits[]/modified[]
以匹配本地映射的路径。Sn
读取文件的utf-8
或base64
副本。T
中重新创建该文件。T
即可完成所有操作。你可能会发现使用本地克隆更好,但我建议先尝试使用 API 方法,看看事情是否容易实现。
我们遇到了类似的问题 - 我们想要在项目和常用文档存储库之间自动复制文档文件。我们开发了一个工具,监听GitHub的Webhooks,解析提交并创建拉取请求到目标存储库。
我们已经将它开源了 - https://github.com/livechat/copycat - 它可以在任何Node平台服务器上使用。
编辑:我现在意识到这个问题是关于GitHub的。我的答案是关于你有文件访问权限的标准git存储库。
我假设第二个存储库是第一个的克隆,类似于以下方式创建:
git clone --bare first.git second.git
将当前目录更改为first.git
仓库内部,并将second.git
添加为远程仓库。
cd first.git
git remote add second ../second.git
接下来,在文件夹first.git/hooks/
中创建一个名为post-receive
的文件(您可以将已经存在的post-receive.sample
文件重命名)
文件内容应该是这样的
#!/bin/sh
git push second
如果没有第三方服务器监听webhook事件,两个GitHub仓库不能相互镜像。
您需要在一个GitHub仓库上注册一个webhook以侦测推送事件,并将其推送到第二个GitHub仓库。
这意味着需要一个服务器来侦听webhookjson负载。
类似于dustin/gitmirror
这样的工具可以帮助做到这一点(使用Go语言)。
由于您有不同的存储库,您可以尝试使用git-apply/git-am逐个应用提交,然后推送。
假设您在服务器上有Repo1.git和Repo2,其中Repo1.git是裸仓库,Repo2是您第二个存储库的本地克隆。
Repo1/.git/hooks/post-receive
#!/bin/sh
t=$(mktemp)
repo2_directory=/some/place/you/cloned/repo2
error=
while read line; do
ref1=$(echo "$line"|cut -d' ' -f1)
ref2=$(echo "$line"|cut -d' ' -f2)
for ref in $(git log --oneline $ref1..$ref2); do
git show -p --no-color --binary $ref > $t
if !(cd $repo2_directory && git am -q < $t || (git am --abort; false)); then
echo "Cannot apply $ref" >&2
error=1
break
fi
done
[ -n "$error" ] && break
done
rm -f $t
[ -z "$error" ] && (cd $repo2_directory && git push)
一个简单的方法是将两个(或更多)pushurl
添加到origin
(或其他某个远程仓库)。
例如:
git remote set-url --add --push origin url1
git remote set-url --add --push origin url2
这并不会对任何人的工作流程产生太大影响,但所有推送仍然会在两个存储库中有效地重复。更详细的解释可以在这里找到。
如果您有很多人在同一个存储库上工作,并希望反映他们的更改,请尝试运行脚本为每个开发人员分配新的pushurl
。否则,恐怕您需要使用钩子+服务器。