Git 有多种操作用于读取/写入其内部数据库。我读过写操作在 Git 中是原子的。但是,对于读取等其他操作,哪些操作会锁定数据库?
具体来说,我正在编写一个将同时调用“git blame”的应用程序,我想确保这是我可以多线程的东西。
我没有在源代码中检查这一点,但是从了解git的内部结构来看,我会说除此之外的所有内容都git gc
可以是多线程的。
Git 只是一堆相互引用的目标文件,但只允许在一个方向(“过去”)引用。除了分支头之外,git 存储库的内容不能修改(只能扩展),并且git gc
是唯一可以从 git 存储库中删除内容的操作。
这就是为什么 git 需要绝对最小的锁定,也是为什么你应该没问题的原因。请注意,索引除外——它会经常被锁定,但是git blame HEAD
您在裸仓库上运行的每个命令都不会使用索引。
确实需要最少的锁定。
唯一需要注意的是同时运行多个 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 gc
gc
A
gc
B
问题是
kill(pid, 0)
测试失败并出现EPERM
错误,因为B
不允许用户向用户拥有的进程发出信号A
(除非用户B
是root
)。更新测试以将
EPERM
错误识别为意味着进程存在并且gc
不应运行另一个错误(除非--force
给出)。
因此,除非您处于这种情况,否则您可以git
同时调用其他命令而不会出现任何问题。