<story><title>Mtime comparison considered harmful</title><url>https://apenwarr.ca/log/20181113</url></story><parent_chain></parent_chain><comment><author>evmar</author><text>In Ninja I sorta stumbled through some of the same issues described here.  I eventually realized that the interesting question is &amp;quot;does this output file reflect the state of all the inputs&amp;quot; and not anything in particular about mtimes, and that&amp;quot;inputs&amp;quot; includes not only the contents of the input files, but also the executables and command lines used to produce the output.&lt;p&gt;If you squint, mtime&amp;#x2F;inode etc. behave like a weak content signature of the input.  And once you have that perspective, you say &amp;quot;if mtime != mtime I had last time, rebuild&amp;quot;, without caring about their relative values, and that sidesteps a lot of clock skew related issues.  It does &amp;quot;the wrong thing&amp;quot; if someone intentionally pushes timestamps to a point in the past (e.g. when switching branches to an older branch) as an attempt to game such a system, but playing games with mtime is not the right approach for such a thing, totally hermetic builds are.&lt;p&gt;One nice trick is that you can even capture all the &amp;quot;inputs&amp;quot; with a single checksum that combines all the files&amp;#x2F;command lines&amp;#x2F;etc., and that easily transitions between truly looking at file content or just file metadata.   The one downside is that when the build system decides to rebuild something, it&amp;#x27;s hard to tell the user why -- you end up just saying &amp;quot;some input changed somewhere&amp;quot;.</text></comment>
<story><title>Mtime comparison considered harmful</title><url>https://apenwarr.ca/log/20181113</url></story><parent_chain></parent_chain><comment><author>peff</author><text>&amp;gt; the .git&amp;#x2F;index file, which uses mmap, is synced incorrectly by file sync tools relying on mtime&lt;p&gt;This part implies that the index file is written via mmap, but that&amp;#x27;s not true. It is fully rewritten to a new tempfile&amp;#x2F;lockfile, and then atomically renamed into place.&lt;p&gt;Git does not ever mmap with anything but PROT_READ, because not all supported platforms can do writes (in particular, the compat fallback just pread()s into a heap buffer).</text></comment>