Git clone - 引用和并发更新

时间:2016-04-05 09:53:05

标签: git concurrency

我正在调查当有很多用户并且引用的repo自动(并经常)更新时,使用git clone --reference作为优化是否安全。

计划是在一台服务器上会有许多用户使用大量存储库,其中主存储库是远程的(因此很慢)。

为了优化初始克隆速度和服务器磁盘空间,用户将使用执行git clone --reference /home/robot/repo.git <repo>的克隆脚本,以便共享大部分数据。

“机器人”用户将在cron作业上进行频繁的git fetch操作。

现在,我知道当Git存储库由同一个用户拥有和/或目录可写时,对Git存储库的并发访问是安全的,但在这种情况下,引用存储库将是只读的,作为第一个首选项,因此用户将无法在那里写锁文件。

我的问题是,如果“机器人”仓库在另一个用户访问存储库时执行fetch / gc / repack会发生什么?克隆/获取/拉回落到从远程仓库获取,慢慢? log / checkout / rebase等其他命令是否失败?用户存储库中是否会发生损坏?

注意:

  • 我确定用户进程可以在开始阅读之前检查回购是否已锁定;我在询问读取期间发生的写操作。
  • 我知道文档说垃圾收集可能会破坏引用的克隆,但在这种情况下只会有快进更新,因此不会删除任何内容,只会重新打包。
  • 我查看了文档,并没有出现“并发”这个词,所以我很难找到关于这个主题的官方声明。
  • 本网站上的大多数其他问题都是关于并发拉取,推送和提取,在这种情况下它是安全的,因为这些操作是原子的(引用已更改,或者它们没有);共享或引用克隆的情况似乎不太明显,因为它需要连续访问打包的目标文件。
  • 这是在使用本地文件系统的Linux系统上,因此没有网络问题,OS支持,不同的Git版本等没有变化。

1 个答案:

答案 0 :(得分:2)

出于一系列相当复杂的原因,你很安全。

基本上,--reference克隆(没有--dissociate):

  • 将引用的路径写入.git/objects/info/alternates(请参阅the gitrepository-layout documentation
  • 对于它要说的&#34;想要&#34;的每个提交ID,查看替代项以查看它是否可以找到该对象。

假设在发生这种情况时,正在进行某种更新。你的克隆有一些哈希值,并且正在回答问题:&#34;是替代中的这个对象吗?&#34;

假设它找到的答案是&#34; no&#34;。然后它将从原始对象中检索对象,并将永久保留该对象(或者直到它不再需要为止,以先到者为准),所以在这种情况下你很好。

假设它发现答案是&#34;是的,该对象在备用中。&#34;有两种可能性:

  • 对象存储为松散对象,或
  • 对象在一个包中。

如果对象是现在,但正处于打包过程中,对象将很快出现在一个包中,之后松散的对象将被取消链接。在将包完全写入稳定存储之前,引用git存储库不会取消链接松散对象。因此,即使你的克隆在这个序列的中间完成并且你运行另一个需要该对象的git命令,它也会找到松散的对象,或者找到包。

  • 如果找到松散的对象,则打开文件即可。这意味着当引用存储库的git命令取消链接文件时,你的git已经打开并可以使用它。

  • 如果您的git在包中找到该对象,则打开包文件即可。这意味着如果重新打包和删除(未链接)包文件,您的git已经打开并可以使用它。由于打包文件是自包含的, 1 打开的文件就足够了。

唯一出现这种情况的唯一方法是,如果您允许参考存储库删除对象(通过gc或类似对象),这就是文档所警告的内容。如果您打开了对象(以松散或打包的形式),那么您就可以了,但一旦它消失了,以后尝试找到它,就不会。

所有这一切都取决于操作系统保留文件,即使它被删除。某些文件系统( cough NFS cough )不一定表现正常,当然还有任何类型的远程网络文件系统(例如Dropbox) )也可能导致问题。只要您坚持使用本地文件系统(并且您的硬件没有失败),您应该没问题。

1 除了&#34;瘦身&#34;但无论如何都不会在这里看到。