在同一个仓库中同时运行更多的git命令是否安全?

26

我想知道运行诸如git pushgit commit之类的操作是否安全,并行运行它们(例如在cron作业、jenkins作业等中)。在git中是否内置了锁定机制,使这些操作串行化,或者这可能会破坏存储库?

2个回答

21

是的。Git通过以允许此类操作的方式编写引用来工作。如果您在推送时同时进行提交,那么推送将仅从引用向下到它们所包含的对象进行。如果提交完成并及时更新分支引用,则会被推送。否则,旧的引用将被推送。不会出现“半个提交”被推送的情况。

所有文件都是按一种隐式保留任何指针的引用完整性的方式编写的。最后编写的文件将成为已经拥有所有依赖项的引用。


并行提交中,如果涉及到非重叠子集(例如,一个提交涉及一个子树,第二个提交涉及其兄弟节点),该怎么办呢?我担心这可能会导致其中一个提交被设置为HEAD,而第二个提交则悬挂在未命名分支上 :-/ - user1046334
没有问题。只有一个人会赢。从那个运气不佳的人那里获取后续内容将揭示需要合并或重新基于的需求。 - Adam Dymitruk
1
你应该处理仓库上有锁的情况(.git/index.lock)。Git使用这个文件来确保索引不会被损坏。 - jeremy
1
@jeremy:所以如果我想序列化(不重叠,这样才有意义)提交,我只需要锁定.git/index.lock,然后就完成了吗?还是在我的提交上自己加锁更安全(如@AdamDymitriuk所回答的那样)? - user1046334
1
不,.git/index.lock 是自动的,除非出现崩溃情况,否则终端用户不应该触碰它。如果你正在运行多个提交和推送操作,并在 Git 中遇到了 index.lock 错误,你应该执行类似 'git pull' 的操作,并重新尝试你正在尝试的操作。 - jeremy

3
理论上,git commit 部分可能会出现一种罕见的竞态条件,其中 HEAD 文件不可用。
在 Git 2.15.x/2.16(2018年第一季度)之前,这是静默的。但以后就不会再静默了。
请参见 提交 c26de08 (由 Andrey Okoshkin (``) 于 2017年10月20日提交)。
(由 Junio C Hamano -- gitster --提交 4a1638c 中合并,于2017年11月6日)

提交: 检查resolve_ref_unsafe的结果

在打印提交摘要时,添加对已解决HEAD引用的检查。
如果files_read_raw_ref()中的lstat()open()调用失败,则resolve_ref_unsafe()可能会返回NULL指针。
这种情况可能是由于竞争而导致的:文件此时变得不可访问。

消息变为:

if (!head)
    die_errno(_("unable to resolve HEAD after creating commit"));

在 Git 2.36 (2022年第二季度) 中,消息内容已更改:

参见 提交 ce14de0提交 09444e7 (由 Ævar Arnfjörð Bjarmason (avar) 于2022年1月26日提交)。
(由 Junio C Hamano -- gitster -- 合并于 提交 03bdcfc,2022年2月11日)

序列控制器:在refs_resolve_ref_unsafe()失败时不要使用die_errno()

签名作者:Ævar Arnfjörð Bjarmason

更改代码,使其不再关心errno。该代码已经在ed90f04(“refs API:使resolve_ref_unsafe()不设置errno”,2021年10月16日,Git v2.35.0-rc0 -- merge列在batch #1中)中忠实地迁移到新的"resolve_errno" API中。当序列运行后无法解析"HEAD"时,说出"errno"值并没有真正帮助,因为假的后端errno可能与".git/HEAD"的状态无关。随着即将到来的reftable后端,这种虚伪将变得更加明显。因此,在这里使用die()而不是die_errno()会更好。这也有助于简化refs_resolve_ref_unsafe() API。这是唯一一个未忽略"failure_errno"输出参数的用户。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接