缺少 inotify 事件(在 .git 目录中)

Mic*_*mza 11 linux git libc inotify docker

我正在使用 inotify 事件监视文件的更改(碰巧的是,从 Python 调用 libc)。

对于 a 期间的某些文件git clone,我看到了一些奇怪的东西:我看到了一个IN_CREATE事件,并且我通过ls该文件看到了该文件有内容,但是,我从未看到IN_MODIFYIN_CLOSE_WRITE. 这给我带来了问题,因为我想IN_CLOSE_WRITE对文件做出响应:具体来说,要启动文件内容的上传。

行为异常的文件在.git/objects/pack目录中,它们以.packor结尾.idx。git 创建的其他文件有一个更规则的IN_CREATE-> IN_MODIFY->IN_CLOSE_WRITE链(我不关注IN_OPEN事件)。

这是在 MacOS 上的 docker 内部,但我在远程系统中的 Linux 上的 docker 上看到了相同的证据,所以我怀疑 MacOS 方面不相关。如果正在观看并且git clone同一个docker 容器中,我就会看到这一点。

我的问题:

  • 为什么这些文件中缺少这些事件?

  • 可以做些什么呢?具体来说,我如何响应写入这些文件的完成?注意:理想情况下,我想在写作“完成”时做出回应,以避免不必要/(错误地)上传“未完成”的写作。


编辑:阅读https://developer.ibm.com/tutorials/l-inotify/看起来我所看到的与

  • 一个单独的临时文件,名称为tmp_pack_hBV4Alz,正在创建、修改和关闭;
  • 创建到该文件的链接,并带有最终.pack名称;
  • tmp_pack_hBV4Alz名称被删除。

我认为我的问题是尝试使用 inotify 作为上传文件的触发器,然后减少到注意到该.pack文件是另一个文件的硬链接,并在这种情况下上传?

Ent*_*nte 5

git在 Linux 4.19.95 上为2.24.1单独回答您的问题:

  • 为什么这些文件中缺少这些事件?

您看不到IN_MODIFY/IN_CLOSE_WRITE事件,因为git clone将始终尝试对目录下的文件使用硬链接.git/objects。通过网络或跨文件系统边界进行克隆时,这些事件将再次出现。

  • 可以做些什么呢?具体来说,我如何响应写入这些文件的完成?注意:理想情况下,我想在写作“完成”时做出回应,以避免不必要/(错误地)上传“未完成”的写作。

为了捕获硬链接的修改,您必须为 inotifyCREATE事件设置一个处理程序,该事件跟随并跟踪这些链接。请注意,简单CREATE也可能意味着创建了一个非空文件。然后,在IN_MODIFY/IN_CLOSE_WRITE到任何文件上,您还必须对所有链接文件触发相同的操作。显然,您还必须删除DELETE事件中的这种关系。

一种更简单、更健壮的方法可能是定期散列所有文件并检查文件内容是否已更改。


更正

git仔细检查源代码并使用 运行gitstrace,我发现它git确实使用了内存映射文件,但主要用于读取内容。请参阅xmmap始终PROT_READ只调用 with only的用法。. 因此,我在下面的先前答案不是正确答案。尽管如此,为了提供信息,我仍然想把它保留在这里:

  • 你看不到IN_MODIFY事件,因为packfile.c使用mmap的文件访问和inotify不用于报告修改mmap版文件。

    inotify 联机帮助页

    inotify API 不会报告由于 mmap(2)、msync(2) 和 munmap(2) 可能发生的文件访问和修改。