我想自动将后接收挂钩中的提交从LAN上的中央仓库推送到云中的另一个中央仓库。 LAN repo使用git clone --mirror git@cloud:/path/to/repo
或等效命令创建。
因为提交的文件相对于我们的上游带宽会很大,所以完全有可能发生这样的事情:
当LAN repo的post-receive挂钩执行时,将从LAN repo到cloud repo的第二次推送开始,两者将同时运行。
我并不担心git对象。最糟糕的情况是,两者都推送上传所有对象来自Alice的推送,但就我理解git的内部而言,这并不重要。
我关注裁判。 假设Alice推送使用更慢的连接,以便Bill推送完成。假设数据包丢失或其他原因导致挂钩从LAN repo推送到Bill&的云端在从局域网回购推送到爱丽丝的推送云之前,推动完成。如果Alice和Bill都在推动主分支并且Bill的推送首先完成,那么主要参与者将在云回购中做什么?我希望它成为比尔的头,因为这是后来的推动,但我担心这将是爱丽丝的头。
进一步澄清:
我意识到,如果比尔从他的机器推送到局域网回购首先完成,那么爱丽丝从她的机器推送到局域网回购将会失败。在这种情况下,LAN repo的接收后挂钩将不会执行。此外,请假设没有人会进行强制推送,所以如果在LAN回购上运行后接收挂钩,则所有参考更改都是快进的。
答案 0 :(得分:4)
如果Bill的推送完成,那么Alice的推送会失败,因为在更新ref之前,git会确保repo的ref仍然与以前相同。在这种情况下,它不会。 Alice最终会看到错误消息并需要解决问题。比尔在反之亦然的情况下也是如此。所以在你的post-receive钩子中你必须确保repo的原始和新refs现在不同。如果没有,那么根本不要推到新的仓库以节省一些工作。
我仍然在你的场景中看到了一个问题,而且是在推送到云端。您可以通过钩子将两个有效引用推送到云位置时出现相同问题。除非你现在不知道你是否需要在脚本中推送到repo,如果它第一次失败,因为你不知道失败的ref是旧的还是比推的更新...特别是如果他们不是&# 39;简单的快进,可能会不时发生。如果你只是强迫推送无论什么东西都有可能云将有一个旧的参考,直到另一个钩子推动其他东西后来。在Alice的情况下,他会合并来自上游或任何其他解决方案的更改,但脚本可能不应该具有这样的决策能力。
在钩子中,您可以在当前仓库上执行一些脚本魔术以确定时间戳等,并且只有在快进时才会推送,但这看起来很混乱,并且更有可能需要合并。我认为比使用post-receive钩子更好的解决方案是每隔五分钟(或者你想要的频率)使用cron或者预定的任务,只需在远程镜像的主分支上运行git pull。如果您无权访问该回购,则可以使用cron作业从LAN回购执行强制推送。我认为这比钩子更安全,而且不那么复杂。这将确保备份云上的分支每隔几分钟始终处于正确的位置,并且不会冒险推送旧的ref并且永远不会获得最新的ref,直到有来自用户的另一次推送,如钩子那样。
答案 1 :(得分:1)
Git 2.4+ (Q2 2015)将引入原子推送,这将使服务器更容易管理推送订单。
查看Stefan Beller (stefanbeller
)所做的工作:
这增加了原子推送选项的测试 前四个测试检查原子选项是否在良好的条件下工作,最后三个补丁检查原子选项是否阻止在只有一个ref无法更新时推送任何更改。
commit d0e8e09 push.c
:添加--atomic
参数
--[no-]atomic
如果可用,请在远程端使用原子事务 要么更新所有引用,要么出错,不更新引用 如果服务器不支持原子推送,则推送将失败。
--atomic
命令行参数这增加了对send-pack的支持,以协商和使用原子推送 iff服务器支持它。原子推送由新命令激活 line flag
--atomic
。
receive-pack.c
:协商原子推送支持这会将原子协议选项添加到允许
receive-pack
通知客户端它具有原子推送功能。
此提交使先前提交中引入的功能在服务端生效 文档中的更改反映了服务器的协议功能。
atomic
------
如果服务器发送了'
atomic
'能够接受原子推动的能力 如果推送客户端请求此功能,则服务器将在一个原子事务中更新ref 要么更新所有引用,要么都不更新。