我有两个GitHub存储库。
我想自动(可能使用hooks和/或github API)将文件提交到第二个存储库,当它们被推送到第一个存储库时。
第二个存储库不是第一个存储库的克隆,它们的文件夹布局不一定相同,只有一堆共同的文件。
这样做最简单的方法是什么?
如果我不必安装http服务器或学习perl,则可获得积分:)
答案 0 :(得分:8)
如果您正在寻找强大且易于维护的内容,我建议您围绕GitHub Webhooks制定解决方案。是的,它需要你部署一个HTTP服务器,比如一个Node.js server,它需要少量的开发(你的要求是相当具体的),但我认为如果你需要一些可靠的东西它会得到回报低维护。如果您认为这种文件镜像方法仍然是正确的做法,那就考虑了方法和设置工作。
让源存储库(在GitHub上)为S1
,S2
...使用(非重叠)文件集来镜像F1
,F2
.. 。,被发送到目标仓库T
(也在GitHub上),其中相应的文件被认为是只读的。您的要求不同寻常,因为Sn
和T
听起来不是彼此克隆的,它们甚至可能没有任何常见的提交,在这种情况下,这不是推送/获取方案。您还无法保证源文件更新发生一次提交,甚至分组但与非复制更改隔离,因此这不是关于挑选提交。
复制的触发器是将某些文件推送到S1
,S2
...,而不是那些repos的任何开发人员克隆的提交,因此客户端挂钩将无济于事(他们可能很难维护)。 GitHub当然不允许使用通用钩子,所以Webhooks是你最好的解决方案。您可以考虑另一个轮询克隆,它定期从S1
...中提取,执行逻辑然后提交到T,但与Webhooks相比,这听起来很尴尬,这将为您提供可靠的交付,重放功能,良好的审计-trail等。
好处是有很多已经构建的基础设施来支持这种类型的设置,因此您必须编写的实际代码可能非常小。假设您使用Node.js
类型设置:
X-Hub-Signature
验证并为所有Webhooks事件提供简单的事件监听器挂钩。每个S可以有一个端点,或者可能更容易将它们扇入。Sn
映射到Fn
。X-GitHub-Event: push
注册处理程序,并检查repository/name
和commits[]/modified[]
以查找与您的本地地图匹配的路径。utf-8
或base64
副本。T
。此方法允许您在不需要T
的本地克隆的情况下执行所有操作。你可能会发现使用本地克隆会更好,我会先看看API方法有多么简单。
答案 1 :(得分:8)
我们遇到了类似的问题 - 我们希望在项目和常用文档的存储库之间自动复制文档文件。我们构建了一个工具,可以监听GitHub的webhook,解析提交并创建Pull Request到选定的目的地。 我们已经开源了它 - https://github.com/livechat/copycat - 它可以在任何节点平台服务器上使用。
答案 2 :(得分:6)
编辑:我现在意识到问题是关于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/
的{{1}}文件夹中创建一个文件(您可以重命名post-receive
已存在的文件)
内容应为此
post-receive.sample
现在,当您将新提交推送到第一个存储库时,将立即执行从第一个到第二个存储的推送,以便第二个接收提交。
答案 3 :(得分:6)
单独使用两个GitHub存储库(没有第三方服务器监听webhook事件)无法互相镜像。
您需要在一个GitHub存储库上注册webhook以检测推送事件,然后推送到第二个GitHub存储库。
这意味着有一台服务器可以监听webhook json payload。
像dustin/gitmirror
这样的工具可以提供帮助(在Go中)。
答案 4 :(得分:-1)
由于你有不同的回购,你可以尝试使用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)
答案 5 :(得分:-2)
一种简单的方法是将两个(或更多)pushurl
添加到origin
(或其他一些远程)。
例如:
git remote set-url --add --push origin url1
git remote set-url --add --push origin url2
它并没有改变任何人的工作流程,但是所有推送仍然有效地复制了两个回购。我们会更详细地解释here。
如果您有很多人在同一个仓库上工作并想要反映他们的更改,请尝试运行脚本为每个开发人员分配新的pushurl
。否则,我担心你需要使用hooks + server。