Git或libgit2如何处理竞争条件?
我使用Git或libgit2如何处理竞争条件?,git,libgit2,Git,Libgit2,我使用libgit2问自己,如果两个进程同时对同一个repo执行写操作,会发生什么 下面的示例是提交回购协议的简单示例。它由许多命令组成 如果一个进程a执行前3个命令并挂起几秒钟,而另一个进程恰好执行相同顺序的命令,但贯穿所有命令,那么a将继续。我知道这是很少见的,因为Git操作主要是用户交互,用户很少同时使用这两个命令,但我想了解Git中这类种族歧视的理论含义,以确保我不会破坏任何东西 非常感谢 check_lg2(git_repository_index(&index, repo),
libgit2
问自己,如果两个进程同时对同一个repo执行写操作,会发生什么
下面的示例是提交回购协议的简单示例。它由许多命令组成
如果一个进程a执行前3个命令并挂起几秒钟,而另一个进程恰好执行相同顺序的命令,但贯穿所有命令,那么a将继续。我知道这是很少见的,因为Git操作主要是用户交互,用户很少同时使用这两个命令,但我想了解Git中这类种族歧视的理论含义,以确保我不会破坏任何东西
非常感谢
check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL);
check_lg2(git_index_write_tree(&tree_oid, index), "Could not write tree", NULL);;
check_lg2(git_index_write(index), "Could not write index", NULL);
check_lg2(git_tree_lookup(&tree, repo, &tree_oid), "Error looking up tree", NULL);
check_lg2(git_signature_default(&signature, repo), "Error creating signature", NULL);
check_lg2(git_commit_create_v(
&commit_oid,
repo,
"HEAD",
signature,
signature,
NULL,
comment,
tree,
parent ? 1 : 0, parent), "Error creating commit", NULL);
Git使用了几种方法来处理这种情况,而libgit2使用了相同的方法来实现兼容性 当Git需要用固定名称更新文件时,如索引或引用,它会创建一个同名文件,但以
结尾。使用O_create
和O_exc
锁定
,然后将新内容写入该文件。然后对现有文件使用原子重命名。在Unix系统上,这意味着打开旧文件的进程将看不到任何更改,而新进程将打开新文件
如果您将一个对象写入对象存储,比如树或提交,这是无竞争的,因为它的名称是唯一的。文件存在或不存在,如果不存在,则将其创建为临时文件并重命名到位。重命名意味着,如果一个相同的对象已经存在,它将被替换为一个相同的副本
现在,有可能您想要编写一个文件,比如索引,而其他人已经在这样做了,在这种情况下,您必须等待锁文件消失。通常等待的时间很短,所以等待不是问题。对于索引之类的东西,libgit2提供了内存中的索引,这两种索引都不需要锁定,如果您决定不需要它们,则更容易丢弃
请注意,Git不能保证工作树中的原子操作,因为如果出现问题,就不可能完全回滚。如果您只是处理存储库内容,而没有更新工作树,那么Git应该没有竞争条件,并且对于多个用户来说性能合理。不知道libgit2。。。但是git会在发生某些事情时锁定索引。在修改索引的整个操作中,Git2也会锁定索引。