On Windows, which has separate file and directory symlinks, gitoxide falls back to creating file symlinks when the target is not found, since 31d02a8 (#1363), to support dangling symlinks (#1354). I wish to create file symlinks in even more situations, to fix #1420 and #1421. But this runs the risk of accidentally converting situations where directory symlinks are currently being created into situations where file symlinks are created.
On a feature branch which should never be merged, I tried deliberately breaking symlink creation to only ever create file symlinks on Windows. Enabling CI on that branch reveals that this breaking causes no existing tests to fail. I have also produced this effect locally.
Ordinarily I would just open a PR that adds a test. I intend to open a PR that fixes #1420 and hopefully also #1421, and to include a test that a symlink to a directory is created as a directory symlink on Windows. I plan to include it there so that it validates that my fix there does not break this functionality. I am also opening an issue for this, for two reasons:
- If, for simplicity, the new test is not wanted in that PR, then it can be removed and the need for it will still not be forgotten.
- It is not obvious how this test should be done, or how thoroughly it should be done. Rather than have that PR be the only place to discuss it, I'm opening this issue so that possible concerns with the approach I plan to take can be easily raised.
On that second point, the approach I am thinking of taking is actually not to check the created symlink type at all, but instead to write an operating-system agnostic test that will fail on Windows if the wrong type of symlink is created, testing the actual functionality of the symlink.
Some experiments I have done reveal that obtaining metadata with std::fs::metadata
will fail to traverse through the wrong type of symlink to access metadata on the target. (This is not for lack of trying. Unlike symlink_metadata
, which is lstat
-like, the metadata
function is stat
-like and attempts to obtain metadata of the ultimate target of the symlink.) Therefore, a test can simply attempt to do that, and also assert that the target is a directory; together, that should provide both validation and insight into what goes wrong if there is a regression.
The advantage of that approach is that it tests the desired behavior that symlinks to directories are, when possible, created in a way that actually works, on all systems, including Windows where it happens to be easy to get that wrong.
The disadvantage is that I am not sure the inability to traverse through the wrong type of symlink to obtain metadata is a guaranteed part of the behavior of the metadata
function in the Rust standard library.
If this approach is inadequate, then it could either be complimented or supplanted by another test that uses Windows-specific functions to check the actual type.