Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git或libgit2如何处理竞争条件?_Git_Libgit2 - Fatal编程技术网

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也会锁定索引。