自动将推送的文件从一个GitHub存储库复制到另一个存储库

时间:2015-05-22 15:04:10

标签: git github github-api githooks

我有两个GitHub存储库。

我想自动(可能使用hooks和/或github API)将文件提交到第二个存储库,当它们被推送到第一个存储库时。

第二个存储库不是第一个存储库的克隆,它们的文件夹布局不一定相同,只有一堆共同的文件。

这样做最简单的方法是什么?

如果我不必安装http服务器或学习perl,则可获得积分:)

6 个答案:

答案 0 :(得分:8)

如果您正在寻找强大且易于维护的内容,我建议您围绕GitHub Webhooks制定解决方案。是的,它需要你部署一个HTTP服务器,比如一个Node.js server,它需要少量的开发(你的要求是相当具体的),但我认为如果你需要一些可靠的东西它会得到回报低维护。如果您认为这种文件镜像方法仍然是正确的做法,那就考虑了方法和设置工作。

让源存储库(在GitHub上)为S1S2 ...使用(非重叠)文件集来镜像F1F2 .. 。,被发送到目标仓库T(也在GitHub上),其中相应的文件被认为是只读的。您的要求不同寻常,因为SnT听起来不是彼此克隆的,它们甚至可能没有任何常见的提交,在这种情况下,这不是推送/获取方案。您还无法保证源文件更新发生一次提交,甚至分组但与非复制更改隔离,因此这不是关于挑选提交。

复制的触发器是将某些文件推送到S1S2 ...,而不是那些repos的任何开发人员克隆的提交,因此客户端挂钩将无济于事(他们可能很难维护)。 GitHub当然不允许使用通用钩子,所以Webhooks是你最好的解决方案。您可以考虑另一个轮询克隆,它定期从S1 ...中提取,执行逻辑然后提交到T,但与Webhooks相比,这听起来很尴尬,这将为您提供可靠的交付,重放功能,良好的审计-trail等。

好处是有很多已经构建的基础设施来支持这种类型的设置,因此您必须编写的实际代码可能非常小。假设您使用Node.js类型设置:

  • 部署github-webhook-handler。这个很酷的小库是GitHub Webhooks的预构建处理程序,它处理HMAC X-Hub-Signature验证并为所有Webhooks事件提供简单的事件监听器挂钩。每个S可以有一个端点,或者可能更容易将它们扇入。
  • 将一些本地文件(保存在Git仓库中)将Sn映射到Fn
  • X-GitHub-Event: push注册处理程序,并检查repository/namecommits[]/modified[]以查找与您的本地地图匹配的路径。
  • 部署node-github,Node.js的GitHub APIv3实现。
  • 对于每个匹配的文件:
    • 致电getBlob,从Sn中读取该文件的utf-8base64副本。
    • 致电createBlob,在T
    • 中重新创建该文件
    • 对T进行一系列调用getReference(当前提交),getTreecreateTree(从基础和新blob创建一个新的){{3}最后createCommit。这是一个工作流程 - 一个较低的冲突就是分支/合并。

此方法允许您在不需要T的本地克隆的情况下执行所有操作。你可能会发现使用本地克隆会更好,我会先看看API方法有多么简单。

enter image description here

答案 1 :(得分:8)

我们遇到了类似的问题 - 我们希望在项目和常用文档的存储库之间自动复制文档文件。我们构建了一个工具,可以监听GitHub的webhook,解析提交并创建Pull Request到选定的目的地。 Copycat schema 我们已经开源了它 - 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。