【问题标题】:Locking strategy of git to achieve concurrency?git实现并发的加锁策略?
【发布时间】:2013-11-26 12:58:50
【问题描述】:

所以我最近一直在阅读有关如何设置 git 服务器的内容,并在发现根本不需要特定的守护进程(只是一个带有文件系统的 SSH 服务器)后,我开始更多地研究如何设置 git在后台管理文件。

每个提交如何在 .objects 文件夹中表示以及如何将所有内容组合在一起的策略非常聪明,但似乎没有明确提到这种方法实际上使 git 以非常简单的方式实现并发,而无需需要一个信令服务器。

尽管如此,在某些情况下无法保证并发性,这基本上是在重写历史时(强制推送)。在这种情况下,树中是否使用了任何锁定策略来避免并发问题?是否有更多关于此主题的文档?

this SO answer 中对这个话题有所提及,但非常简短。)

【问题讨论】:

    标签: git concurrency git-push git-filter-branch


    【解决方案1】:

    git 数据结构是不可变的,除了 refs(即分支/标签/等),“重写历史”不是很正确的术语,更适合“创建替代历史”。回购将包含所有对象 - 新的和旧的。此外,在“推送”对象期间在本地存储库中创建的所有更改都只是传输。然后你推送它,它首先发送所有对象(因为对象是由它的内容定义的,所以它们是唯一的,不存在并发问题)。发送完所有对象后,引用正在发生变化。它只是一个很小的单个文件(refs/heads/<branchName>),可以用 40 字节的 sha1 键覆盖。据我所知,它会对文件进行原子比较和设置更改。它读取旧的 ref 值,创建一个锁文件,检查旧值是否不变,用新的 sha1 替换并删除锁。如果失败,则推送失败,需要重试(即乐观锁)。您可以从source code,update_ref 函数中了解更多详细信息。

    强制推送后可能会出现一些“松散的对象”(即没有从任何现有 ref 引用的对象),因此这些对象稍后会被垃圾回收。

    非常聪明和整洁。

    【讨论】:

    • 谢谢!关于垃圾收集如何工作的任何参考?因为我认为这是一个本地工作副本操作,而不是客户端可以在服务器上执行的操作
    【解决方案2】:

    在必要时创建各种文件以充当锁。 Git 创建一个名为.git/index.lock 的文件来锁定索引。 git index-pack 可以创建一个.keep 文件来防止竞争条件。可能还有更多例子。

    【讨论】:

    • 值得一提的是,index.lock 用于 git 索引,因此仅用于提交,即仅在本地存储库中,通常由单个用户使用。要推送到远程仓库,不需要使用 index.html。 index-pack 通常在git gc 期间使用。
    猜你喜欢
    • 2023-04-01
    • 2018-09-08
    • 2020-11-21
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 2013-05-14
    • 2012-04-16
    相关资源
    最近更新 更多