离线同步本地中心的git存储库

时间:2019-03-23 23:52:11

标签: git git-bundle

我们有两个不同的团队,每个团队都在自己的位置上与git合作,每个位置都有一个参考资料库。每个位置都可以访问企业网络,但是两个网络不能直接连接(请问我,请问我):我们只能交换文件。我们希望能够定期同步这两个位置,以便可以通过各自的参考资料库共享工作。

要求:

  • 必须允许双向交流。
  • 即使我们希望大部分时间都在单独的分支上工作,我们也需要能够从双方同时在某些分支上工作,或者至少从发生这种情况的情况中恢复过来。这意味着可能需要整合步骤来处理分散的工作。
  • 大多数跟踪必须自动进行,以使手动干预和由此产生的操作错误的风险最小化(不是致命的,但最好避免指责:信任受到限制)。尤其是,在git-bundle手册页中使用的单个移动标签示例是可笑的,因为即使到有限数量的分支(我们有几十个分支),它也无法缩放。
  • 只能通过远程推/拉操作以及在必要时进行轻度管理操作来操作参考存储库,这既是因为它们在IT控制之下,又因为我们希望它们始终保持一致,即先进行集成,然后进行集成另一方的更改以及集成在本地参考资料库中发布。
  • 我们不能每次都发送整个存储库(甚至是压缩了tar的文件):它本身不仅有点大,而且连续发送的所有程序包都保留在记录中,因为这是合同承诺的一部分,并且有N份那里的存储库很快将变得不可持续。
  • 所有必需的信息必须存储在本地参考存储库中,以便任何开发人员都可以执行同步步骤,而不必依赖于特定开发人员的本地存储库中存储的信息。
  • 至少在可能的范围内使用git而不是反对git。工作流程越怪异,由于git更改或其他意外情况而导致工作中断的可能性就越大。

非要求:

  • 处理两个以上断开连接的站点。两个已经足够具有挑战性了。
  • 夜间处理。交易所将被手动触发和处理。
  • 命令的数量有限或复杂。如果需要许多复杂的命令,我们可以随时在脚本中隐藏这种复杂性。
  • 跨脱机同步。就像流一样,这总是意味着麻烦。因此,我们可以假设离线同步操作是完全有序的,而不管它们的方向如何,必要时可以轮流使用。
  • 分支机构管理细节等。这是我们的内部业务。

1 个答案:

答案 0 :(得分:1)

到目前为止,我的解决方案是使用git bundle命令,依靠远程引用来跟踪其他位置已经存在的内容,我想出了一些涉及的步骤来通过push携带这些远程引用/拉。将我们的位置称为站点a,将远程位置称为站点b。

  • 生成分发包以发送到远程位置:

    1. ~/work$> git clone $LOCAL_REF_URL --mirror bundler
    2. ~/work$> cd bundler
    3. ~/work/bundler$> git bundle create ../bundle-site-a-$(date +%Y-%m-%d) --branches --tags --not --remotes=site-b

    捆绑器工作存储库现在可能会被丢弃。

  • 从远程位置集成捆绑包:

    1. ~/work$> git clone -n $LOCAL_REF_URL bundle-integration
    2. ~/work$> cd bundle-integration
    3. ~/work/bundle-integration$> git checkout --detach
    4. ~/work/bundle-integration$> git fetch origin 'refs/heads/*:refs/heads/*' 'refs/remotes/site-b/*:refs/remotes/site-b/*'
    5. ~/work/bundle-integration$> git remote add site-b ../bundle-site-b
    6. ~/work/bundle-integration$> git fetch --tags site-b 'refs/heads/*'
    7. 这时,获取操作会告诉您哪些远程site-b分支已使用捆绑包中的信息进行了更新,因此请在此处插入必要的工作,以整合在我们所在位置具有相应分支的分支。首先是git fetch . 'refs/remotes/site-b/*:refs/heads/*',可以一击而过,然后是git checkout $BRANCH && git merge site-b/$BRANCH:其他都可以:历史的任何一面都无法重写。此外,删除捆绑软件已考虑但不再包含的分支。
    8. 如果git push --tags origin 'refs/heads/*:refs/heads/*' 'refs/remotes/site-b/*:refs/remotes/site-b/*' --prune完全成功,则返回;我们完成了
    9. ~/work/bundle-integration$> git fetch origin(常规)
    10. 要考虑到您忙于执行上述步骤时在您的位置上完成的工作;除您自己的合并工作外,仍然必须通过合并完成操作(尽管在更常见的git checkout $BRANCH && git merge origin/$BRANCH习惯用法中),如果您愿意的话可以重新设置工作
    11. 转到8

    bundle集成工作存储库现在可能会被丢弃。

    注意:第1步不能只是镜像克隆,因为--mirror不仅会假定--bare,还会强制执行它,这与以后执行集成的需求是不兼容的:即使是琐碎的(快进)git merge操作需要一个非裸仓库。为了使HEAD远离任何分支,必须执行第3步,否则,如果第4步试图直接更新HEAD指向的分支,则第4步将失败。步骤4是必需的(它不会获取任何提交),因为它将设置所有必要的引用,因为远程捆绑包可能不一定包含所有分支(它省略了不提供任何更新的分支),最后,我们将继续根据我们自己的分支从起源修剪分支,所以我们要从所有起源的分支开始;在此步骤中将refspecs指定为-c选项,而不是将初始克隆指定为初始克隆。第5步是必需的,因此git知道在第6步中更新refs/remotes/site-b/*中的引用。

  • 当远程位置已确认能够提取发送给他们的分发包的内容时,更新远程跟踪引用:

    这是按照“从远程位置集成分发包”中的步骤完成的,除了将已发送的分发包当作来自远程位置的分发包一样;显然,在这种情况下,无需进行整合工作,因为来自我们位置的分支机构必须与捆绑包中的信息保持最新。