离线同步本地中央git存储库 [英] Offline syncing of locally-central git repositories

查看:76
本文介绍了离线同步本地中央git存储库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have two different teams, each in its own location, working with git, each location having a reference repository. Each location has a access to an enterprise network, but the two networks cannot be directly connected (trust me, we asked): we can only exchange files. We would like to be able to sync the two locations regularly so that the work can be shared through the respective reference repositories.

要求:

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

非要求:

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

推荐答案

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

The solution I have so far is to use the git bundle command, relying on remote references to keep track of what the other location already has, with some involved steps I came up with to carry these remote references through push/pull. Let our location be called site-a and the remote location be called site-b.

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

  • Generating a bundle to send to the remote location:

  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 $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

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

The bundler work repository may now be discarded.

从远程位置集成捆绑包:

Integrating a bundle from the remote location:

  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. .我们完成了
  10. ~/work/bundle-integration$> git fetch origin(常规的)
  11. 要考虑到您忙于执行上述步骤时在您的位置上完成的工作;除您自己的合并工作外,仍然必须通过合并完成操作(尽管在更常见的git checkout $BRANCH && git merge origin/$BRANCH习惯用法中),可以根据需要重新设置合并
  12. 转到8
  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. At this point the fetch told which remote site-b branches were updated with info from the bundle, so insert here the work necessary to integrate the ones that have corresponding branches in our location; first a git fetch . 'refs/remotes/site-b/*:refs/heads/*' to fast-forward the ones that can be in one fell swoop, then git checkout $BRANCH && git merge site-b/$BRANCH for the others: neither side of history can be rewritten. Also delete branches that the bundle took into account but no longer contains.
  8. If git push --tags origin 'refs/heads/*:refs/heads/*' 'refs/remotes/site-b/*:refs/remotes/site-b/*' --prune fully succeeds, return; we are done
  9. ~/work/bundle-integration$> git fetch origin (a regular one)
  10. Take into account work done on your location that happened while you were busy performing the previous steps; that still has to be done with merge (though in the more usual git checkout $BRANCH && git merge origin/$BRANCH idiom), except for your own merging work, which can be rebased if you prefer
  11. goto 8

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

The bundle-integration work repository may now be discarded.

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

Notes: step 1 cannot just be a mirror clone, as --mirror does not merely presume --bare, it forces it, which is incompatible with the need to perform integrations later: even trivial (fast-forward) git merge operations require a non-bare repository. Step 3 is necessary in order to "park" the HEAD away from any branch, otherwise step 4 is going to fail if and when it tries to directly update the branch that HEAD is pointing to. Step 4 is necessary (it does not fetch any commit) as it will set up all the necessary references since the remote bundle may not necessarily contain all branches (it omits ones where it provides no update), while in the end we're going to prune branches from the origin based on our own branches, so we want to start with all the branches origin has; specifying the refspecs from this step as -c options to the initial clone instead does not appear to work. Step 5 is necessary so git knows to update the references in refs/remotes/site-b/* in step 6.

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

Updating the remote tracking references, when the remote location has confirmed having been able to fetch the contents of a bundle sent to them:

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

This is done by following the steps from "Integrating a bundle from the remote location", except taking the sent bundle as if it was coming from the remote location; obviously no integration work is necessary in that case as the branches from our location are necessarily up-to-date with the information from the bundle.

这篇关于离线同步本地中央git存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆