git 工作树中的偶尔"fatal: not a git repository"



我有4台Ubuntu机器,Jenkins作业在它们上运行。一个共享磁盘作为/data/repositories/安装到它们上。在它下面,有许多由git clone <url> --no-checkout -b master创建的非裸存储库。

当作业被触发时,它会运行以下步骤:

  1. /data/repositories/foo中,获取Branch ABranch B
  2. 解析Branch B头并获取其提交SHA1VALUE
  3. 通过git worktree add --no-checkout /path/to/worktree SHA1VALUE创建工作树
  4. Branch A头中获取更改后的文件
  5. /path/to/worktree中启用稀疏签出
  6. 将更改后的文件写入/data/repositories/foo/.git/worktrees/xx/info/sparse-checkout
  7. /path/to/worktree中运行git checkout以签出这些文件
  8. 使用git cherry-pickBranch A头应用于/path/to/worktree中的SHA1VALUE
  9. 将新提交推送到Branch B

/path/to/worktree不在共享磁盘上,而是在每台机器自己的磁盘上。在步骤7和步骤9中,它可能偶尔会引发错误fatal: not a git repository /data/repositories/foo/.git/worktrees/xx。当错误发生时,/data/repositories/foo/.git/worktrees/xx不在那里,就好像它在步骤之前被某个进程或线程删除了一样。在作业中,在作业完成或在这些步骤中引发异常之前,不会故意删除它。

如果使用相同的参数重新生成作业,则问题不会再次出现。

如果/data/repositories/foo/.git/worktrees/xx一开始没有成功创建,那么它将在这些步骤中被检测到,并且步骤8总是失败。

多个作业可以同时在同一个/data/repositories/foo上运行。但在/data/repositories/foo/.git/worktrees/xx/info/sparse-checkout中,xx部分是唯一的。

谢谢你提供任何线索。

感谢@torek。虽然还不清楚问题的确切原因,但我找到了解决方案。根据解决方案,正如@torek所指出的,根本原因很可能与种族条件和文件系统类型有关。

共享磁盘为NFS,非共享磁盘为EXT4。因此,主存储库位于NFS系统中,其工作树在EXT4系统中创建。在并发作业运行的某些未知条件下,主存储库中的工作树gitdir会被意外删除,当然工作树也会被禁用。

解决方案是在共享磁盘中创建工作树,以便主存储库和工作树位于同一磁盘上。测试大约8小时后,问题不会再次出现。

最新更新