pack_dirstate: only invalidate mtime for files written in the last second
Previously we'd place files written in the last second in the lookup set. This
can lead to pathological cases where a file always remains in the lookup set if
it gets modified before the next time status is run.
With this patch, only the mtime of those files is invalidated. This means that
if a file's size or mode changes, we can immediately declare it as modified
without needing to compare file contents.
dirstate.status: don't ignore symlink placeholders in the normal set
On Windows, there are two ways symlinks can manifest themselves:
1. As placeholders: text files containing the symlink's target. This is what
usually happens with fresh clones on Windows.
2. With their dereferenced contents. This happens with clones accessed over NFS
or Samba.
In order to handle case 2,
ca6cebd8734e made dirstate.status ignore all symlink
placeholders on Windows. It doesn't ignore symlinks in the lookup set, though,
since those don't have the link bit set. This is problematic because it
violates the invariant that `hg status` with every file in the normal set
produces the same output as `hg status` with every file in the lookup set.
With this change, symlink placeholders in the normal set are no longer ignored.
We instead rely on code in localrepo.status that uses heuristics to look for
suspect placeholders.
An upcoming patch will test this out by no longer adding files written in the
last second of an update to the lookup set.
localrepo.status: ignore empty symlink placeholders
A symlink's target should never be empty in normal use. Solaris and some BSDs
do allow empty symlinks to be created (with varying semantics on dereference),
but a symlink placeholder that started off as empty is either
- going to be empty, in which case ignoring it is fine, since it's unchanged, or
- going to not be empty, in which case this check is irrelevant.