HomePhabricator

merge: fix race that could cause wrong size in dirstate

Description

merge: fix race that could cause wrong size in dirstate

The problem is that hg merge/update/etc work the following way:

  1. figure out what files to update
  2. apply the update to disk
  3. apply the update to in-memory dirstate
  4. write dirstate

where step3 looks at the filesystem and assumes it sees the result of
step2. If a file is changed between step2 and step3, step3 will record
incorrect information in the dirstate.

I avoid this by passing the size step3 needs directly from step2, for
the common path (not implemented for change/delete conflicts for
instance).

I didn't fix the same race for the exec bit for now, because it's less
likely to be problematic and I had trouble due to the fact that the
dirstate stores the permissions differently from the manifest (st_mode
vs '' 'l' 'x'), in combination with tests that pretend that symlinks
are not supported.

However, I moved the lstat from step3 to step2, which should tighten
the race window markedly, both for the exec bit and for the mtime.

Differential Revision: https://phab.mercurial-scm.org/D6475