问题 Git存储库是否可以进行并发操作?


有两种我感兴趣的场景。

  • 存储库是共享的,两个用户希望同时将更改推送到存储库
  • 我想使用cron作业安排每晚或每周“gc”。它运行,有人想在操作期间推送或克隆。

在这两种情况下都存在腐败风险吗?


2237
2017-10-23 21:00


起源

对于#1,我假设你在谈论并发推送到不同的分支?在SO上的其他地方回答并发推送到同一分支。 - cmbuckley
你能提供一个链接吗? - dromodel
q8424232; q6028141 可能也很有趣。 - cmbuckley


答案:


Git允许使用a进行并发操作 悲观并发控制

必要时,git会创建一些特殊文件来充当锁。

特别是,每次操作修改索引时,git都会创建一个名为的文件 index.lock 在里面 .git 用于锁定共享资源的目录。 Git需要其他锁文件:例如,a .keep 文件是在 git index-pack 操作。

通常,您不必担心使用git进行并发操作:它经过精心设计以支持它们。

有人可以告诉你不要担心表演 gc 有了cron的工作,因为git本身会触发 gc 时。即使这是真的,也是如此 手册页 本身建议:

Users are encouraged to run this task on a regular basis 
within each repository to maintain good disk space utilization
and good operating performance.

因此,我认为安排一个工作任务来运行git的垃圾收集并不是一个坏主意。我只是想知道这是不成熟的优化还是你想要解决一个真实的,有问题的问题。我个人从来没有遇到过需要我手动运行的问题 gc,但如果你的情况完全不同,我不会感到惊讶。


10
2018-04-26 08:13





一般来说, ”git gc“可能会删除另一个并发进程的对象 正在使用但尚未创建引用。
Git 2.12(2017年第一季度)有更多内容。

看到 提交f1350d0 (2016年11月15日)by Matt McCutchen(mattmccutchen
(合并 Junio C Hamano - gitster  -  在 提交979b82f,2017年1月10日) 

看看 杰夫金的评论

现代版本的git做了两件事来帮助解决这个问题:

  • “最近”对象引用的任何对象(在2中   周)也被认为是最近的。所以如果你创建一个新的提交   即使在引用提交之前,指向树的对象   那棵树受到保护

  • 当一个对象写入被优化,因为我们已经有了   对象,git将更新文件上的mtime(松散的对象或   packfile)来清新它

但这并不完美。您可以决定引用现有的   对象就像它被删除一样。修剪过程本身就是   不是原子的(并且因为我们的原因而制造它是很棘手的   由文件系统承诺)。

如果您有长时间运行的数据(比如,可能是临时索引文件)   字面上坐了几天或几周)我认为这是一个潜力   问题。解决方案可能是以某种方式使用refs来指出   对你的对象。
  如果你担心短期操作在哪里   有人碰巧跑了 git-gc同时,我同意这是可能的   问题,但我怀疑你在实践中可以忽略的东西。

对于繁忙的多用户服务器,我建议完全关闭auto-gc,   并手动重新包装“-k“ 为了安全起见。

这就是为什么 git gc 手册页 现在包括:

另一方面,当'git gc'与另一个进程同时运行,   存在删除其他进程正在使用的对象的风险   但尚未创建引用。这可能只会导致其他过程   如果其他进程稍后添加a,则失败或可能损坏存储库   对已删除对象的引用。

Git有两个功能可以显着缓解这个问题:

  • 任何修改时间比对象更新的对象 --prune 保留日期,   以及从它可以到达的一切。

  • 将对象添加到数据库的大多数操作都会更新   如果对象已经存在则修改对象#1   适用。

但是,这些功能缺乏完整的解决方案,所以用户们   同时运行命令必须承受一些腐败风险(其中   实际上似乎很低)除非他们关闭自动垃圾   用'git config gc.auto 0'收集。


2
2018-01-15 17:55





如果我跑 git status 在同一台机器上同时进行多个回购,我遇到了重大问题。我即将就此提交一份报告。我认为没有理由不应该这样做或为什么它应该引起问题。


0
2017-08-04 21:43