Skip to content

Commit

Permalink
FunctionalTests: use rename(2) for files on POSIX
Browse files Browse the repository at this point in the history
On macOS and Linux platforms, we use rename(2) directly when
moving files with the SystemIORunner's MoveFile() method, instead
of using .NET Core's File.Move() method.  The latter actually
implements most file moves using a combination of link(2)
followed by unlink(2) on the source file.

The consequence of using link() instead of rename() is that on
recent versions of macOS, when running with Watchman, file
creation events may not be delivered by Watchman to Git when a
new hard link within the Git working tree is created if that
link points to an existing inode outside of the watched tree.
This in turn causes the MoveFileFromOutsideRepoToInsideRepoAndAdd()
test in GitCommandsTests to fail intermittently.

We can work around the problem by utilizing rename() directly, which
also parallels the behaviour of SystemIORunner's RenameDirectory()
method, added in commit 0a517fa.

See also:

facebook/watchman#858
https://github.com/dotnet/runtime/blob/94515f7bd34aabaab5ba6a1316f4a881cbf2370c/src/libraries/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs#L142-L144
  • Loading branch information
chrisd8088 committed Sep 30, 2020
1 parent efb5829 commit bc3e9b3
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion Scalar.FunctionalTests/FileSystemRunners/SystemIORunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,20 @@ public override bool FileExists(string path)

public override string MoveFile(string sourcePath, string targetPath)
{
File.Move(sourcePath, targetPath);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
File.Move(sourcePath, targetPath);
}
else
{
// Use rename(2) on POSIX instead of separate link(2)/unlink(2)
// calls, which File.Move() uses to avoid overwriting the
// target file should it exist. However, using link(2)
// results in unexpected missed event notifications from
// Watchman to Git's fsmonitor hook on some macOS versions,
// which in turn results in test failures for Scalar.
Rename(sourcePath, targetPath);
}
return string.Empty;
}

Expand Down

0 comments on commit bc3e9b3

Please sign in to comment.