如果第二次推送只有第一次推送的快进,那么并发git推送总是安全的吗?

如果第二次推送只有第一次推送的快进,那么并发git推送总是安全的吗?,git,concurrency,backup,automated-tests,git-post-receive,Git,Concurrency,Backup,Automated Tests,Git Post Receive,我想自动将post接收钩子中的提交从局域网上的中央回购推送到云中的另一个中央回购。LAN repo是使用git clone--mirror创建的git@cloud:/path/to/repo或等效命令 因为提交的文件相对于我们的上游带宽来说会很大,所以完全有可能发生这样的情况: Alice发起了一个到LAN repo的推送 当post接收挂钩运行时,Bill从LAN repo中拉出。 LAN回购正处于向云回购的推进中。 这也意味着,比尔的本地回购协议中包含了最重要的内容。通过测试确认 比尔发

我想自动将post接收钩子中的提交从局域网上的中央回购推送到云中的另一个中央回购。LAN repo是使用git clone--mirror创建的git@cloud:/path/to/repo或等效命令

因为提交的文件相对于我们的上游带宽来说会很大,所以完全有可能发生这样的情况:

  • Alice发起了一个到LAN repo的推送
  • 当post接收挂钩运行时,Bill从LAN repo中拉出。
      LAN回购正处于向云回购的推进中。
    • 这也意味着,比尔的本地回购协议中包含了最重要的内容。通过测试确认
  • 比尔发起推动局域网回购。
    • 比尔的推动是爱丽丝推动的快进,因此局域网回购协议将接受它
  • 当LAN repo的post receive钩子执行时,将启动从LAN repo到cloud repo的第二次推送,两次推送将同时运行

    我不担心git对象。最坏的情况是,两个推送都会上载Alice推送中的所有对象,但就我理解git的内部结构而言,这并不重要

    我担心裁判。假设Alice使用速度慢得多的连接推送,那么Bill的推送首先完成。假设数据包丢失或其他原因导致钩子从LAN repo推送到Bill推送到云之前,钩子从LAN repo推送到Alice推送到云。如果Alice和Bill都在推主分支,而Bill的推先完成,那么云回购协议上的主ref是什么?我希望它是比尔的头,因为这是后来的推动,但我担心它会是爱丽丝的头

    进一步澄清:


    我意识到,如果比尔从她的机器到局域网回购的推送先完成,爱丽丝从她的机器到局域网回购的推送就会失败。在这种情况下,lanrepo的post-receive钩子将不会执行。此外,请假设没有人进行强制推送,因此如果post receive挂钩在LAN repo上运行,则所有ref更改都是快进的。如果Bill的推送首先完成,Alice的推送将失败,因为在ref更新之前,git确保repo的ref仍然与以前相同。在这种情况下,情况不会如此。Alice最终会看到错误消息,需要解决问题。比尔也是如此,反之亦然。因此,在您发布的接收挂钩中,您必须确保回购协议的原始参考和新参考现在有所不同。如果没有,那么根本就不要为了节省一些工作而推进新的回购协议

    不过,我仍然看到您的场景中存在一个问题,那就是向云的推进。钩子将两个有效的参照向上推到云位置时也会出现同样的问题。除非现在你不知道如果它第一次失败,你是否需要在脚本中推送到回购协议,因为你不知道失败的ref是比推送的旧还是新。。。特别是如果他们不是简单的快进,这可能会不时发生。如果你只是强迫推球,不管发生什么,云有可能会有一个旧的裁判,直到另一个钩子推起其他东西。在Alice的例子中,他会合并来自上游或任何数量的其他解决方案的更改,但脚本可能不应该具有这样的决策能力

    在hook中,您可能能够对当前回购协议执行一些脚本魔术,以确定时间戳等,并且只有在存在快进时才推送,但这看起来很混乱,而且更可能需要合并。我认为比使用post-receive钩子更好的解决方案是每五分钟使用一个cron或调度的任务(或者无论您希望的频率如何),它只是在远程镜像的主分支上运行一个git pull。如果您没有访问该repo的权限,您可以使用cron作业从LAN repo执行强制推送。我认为这比钩子更安全,也不那么复杂。这将确保备份云上的分支每隔几分钟始终位于正确的位置,并且不会像钩子一样冒险推送较旧的ref,直到用户再次推送,才会得到最新的ref。

    将引入原子推送,这将使服务器更容易管理推送订单。
    请参阅以下人员完成的工作:

    • t5543-atomic-push.sh:添加原子推送的基本测试
    这增加了对原子推送选项的测试。
    前四个测试检查原子选项是否工作良好,最后三个补丁检查原子选项是否阻止在只有一个ref无法更新时推送任何更改。

    • push.c
      :添加一个
      --原子的
      参数

        --[no-]atomic
      
    在远程端使用原子事务(如果可用)。
    要么更新所有引用,要么出错时不更新引用。
    如果服务器不支持原子推送,推送将失败

    • :send pack.c:add
      --原子
      命令行参数
    这增加了对发送包进行协商和使用原子推送的支持 如果服务器支持它。原子推送由新命令激活 行标志<代码>--原子

    • receive pack.c
      :协商原子推送支持
    这将原子协议选项添加到允许
    接收包
    ,以通知客户端它具有原子推送功能
    此提交使上一次提交中引入的功能对服务方生效。
    文档中的更改反映了服务器的协议功能

    如果服务器发送“
    原子”
    ”功能,则它能够接受原子推送
       atomic
       ------