5

Git 有多种操作用于读取/写入其内部数据库。我读过写操作在 Git 中是原子的。但是,对于读取等其他操作,哪些操作会锁定数据库?

具体来说,我正在编写一个将同时调用“git blame”的应用程序,我想确保这是我可以多线程的东西。

4

2 回答 2

1

我没有在源代码中检查这一点,但是从了解git的内部结构来看,我会说除此之外的所有内容都git gc可以是多线程的。

Git 只是一堆相互引用的目标文件,但只允许在一个方向(“过去”)引用。除了分支头之外,git 存储库的内容不能修改(只能扩展),并且git gc是唯一可以从 git 存储库中删除内容的操作。

这就是为什么 git 需要绝对最小的锁定,也是为什么你应该没问题的原因。请注意,索引除外——它会经常被锁定,但是git blame HEAD您在裸仓库上运行的每个命令都不会使用索引。

于 2013-07-15T20:37:01.943 回答
1

确实需要最少的锁定。

唯一需要注意的是同时运行多个 git gc,如Kyle J. McKay (mackyle)为 Git提交的 ed7eda8所示1.9/2.0(2014 年第一季度),实际上是 Git 1.8.5.3,于 2014 年 1 月 15 日发布。

64a99eb4 (git 1.8.5) 开始,如果同一存储库上的另一个进程已经在运行,则git gc拒绝在没有该--force选项的情况下运行。gc

但是,如果存储库是共享的并且用户在存储库上A运行git gc,并且当它gc仍在运行时,用户在同一个存储库上运行,用户运行的B进程将不会被注意到,用户运行的进程将继续运行。git gcgcAgcB

问题是kill(pid, 0)测试失败并出现EPERM错误,因为B不允许用户向用户拥有的进程发出信号A(除非用户Broot)。

更新测试以将EPERM错误识别为意味着进程存在并且gc不应运行另一个错误(除非--force给出)。

因此,除非您处于这种情况,否则您可以git同时调用其他命令而不会出现任何问题。

于 2014-01-12T14:54:32.017 回答