-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Treat mount point as symlink-like in finddata2dirent #4383
base: main
Are you sure you want to change the base?
Conversation
compat/win32/dirent.c
Outdated
@@ -19,7 +19,7 @@ static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAW *fdata) | |||
|
|||
/* Set file type, based on WIN32_FIND_DATA */ | |||
if ((fdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) | |||
&& fdata->dwReserved0 == IO_REPARSE_TAG_SYMLINK) | |||
&& fdata->dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we agree this is the right thing to do for IO_REPARSE_TAG_MOUNT_POINT
, wouldn't we want to keep doing the same thing for IO_REPARSE_TAG_SYMLINK
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably; I'm happy to do both if that sounds correct, though no test changed. There is code that exists in the repo already that appears to treat both equivalently, though, not always.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a drive-by observation, but yeah, I think you'd want to check for either reparse_tag value here -- but I haven't actually tried to dig into this yet. There are several other places in the code where it looks for either type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I appreicate the review. I'll add that on when I get a chance.
I would normally say that such a thing should get extracted to a helper so that everything can evenly decide what is "symlink-like", but truthfully I'm so rusty in C that I don't trust myself to make that work how people'd want 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the PR to allow for both.
Testing on a pnpm monorepo containing recursive symlinks, it turns out that dwReserved0 is actually IO_REPARSE_TAG_MOUNT_POINT. Checking FILE_ATTRIBUTE_REPARSE_POINT and IO_REPARSE_TAG_MOUNT_POINT appears to match similar code in mingw.c's mingw_is_mount_point. The new test fails without this change, but I am unsure whether or not it needs some sort of conditional that checks that symlinks are available in Windows. "SYMLINK" used in the test file appears to be false even though I have developer mode enabled, allowing them. Signed-off-by: Jake Bailey <jabaile@microsoft.com>
1f3315f
to
482d952
Compare
We had that discussion previously and came to the conclusion that mount points are not symlinks: #437 (comment) The main take-away is that mount points are a fundamentally different thing than symbolic links and asking Git to treat them alike is prone to cause trouble. Having said that, a compromise that might work for all involved could be to introduce a new Git attribute (similar to |
@@ -19,7 +19,7 @@ static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAW *fdata) | |||
|
|||
/* Set file type, based on WIN32_FIND_DATA */ | |||
if ((fdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) | |||
&& fdata->dwReserved0 == IO_REPARSE_TAG_SYMLINK) | |||
&& (fdata->dwReserved0 == IO_REPARSE_TAG_SYMLINK || fdata->dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks quite similar to https://github.com/git-for-windows/git/pull/437/files#diff-a6fe7e03ddc742e3276990c88327b92ce59fff378c1be07ed782f0096e131932L20-R21 therefore I suspect that the corresponding change to file_attr_to_st_mode()
might be missing.
I think the thing that gives me pause is that not treating them as symlinks doesn't match the behavior of WSL or For example,
git then does the right thing on a clean, because it is seeing symlinks.
So, if Even powershell's
It's definitely true that these junctions behave weirdly in Explorer, but, I feel like following Explorer isn't the right thing for But, I'm absolutely not an expert; my goal here is to get some sort of resolution to unblock our transition of DefinitelyTyped to a monorepo, and Both pnpm and yarn use junctions by default, likely due to the history of Windows' symlinks previously needing elevated priviledges. However, modern versions of Windows (when in "developer mode") allow symlinks to be created by anyone, so another angle I can try is try and update the package managers to detect this and use "real" symlinks instead, but this seems a lot more challenging and more annoying to have to tell users to enable Developer Mode to get things working. |
Just some further data, but:
So for me, reading the above combined with WSL and git-bash's behavior, I feel like "junctions are symlinks" is the right move for maximum consistency. The thread starting at #437 (comment) is pretty long, so forgive me if I've missed something, but it seems like it's the case that git itself won't make junctions anyhow, so I'm not totally sure what could go wrong by not traversing downward. Maybe the behavior if you attempt to check in one of these things is the problem? |
Hm, I finally read to the bottom of that thread, and through multiple cross references found: #2268 So, it seems like it isn't intentional that But, I'm pretty sure that test is still there and passing, so, maybe it's a different thing entirely. Technically already, But, I'm not sure that PR has an affect, becuase by the time the git clean code gets to things, |
Truthfully I'm not sure how to implement that. The type is set way way down at the root of the thing that translates the Windows API into the more POSIX-y one git uses, so that to me means that there's a setting that affects the APIs needed to read the settings, i.e. in order to know if junctions are symlinks, we have to read the filesystem to pull the attribute config.
I'm not sure I understand this reference; the linked issue seems to be asking for the same behavior I'm asking for, so I can't really re-break if it's already broken, more or less. Maybe I'm missing something in the thread; there's a commit mentioning that issue which has caused github to hide some 3000+ comments. I still disagree in principle that junctions should be treated differently; I think that it's telling that if (In fact, I'm now moderately worried about what |
Testing on a pnpm monorepo containing recursive symlinks, it turns out that dwReserved0 is actually IO_REPARSE_TAG_MOUNT_POINT.
Checking FILE_ATTRIBUTE_REPARSE_POINT and IO_REPARSE_TAG_MOUNT_POINT appears to match similar code in mingw.c's mingw_is_mount_point.
The new test fails without this change, but I am unsure whether or not it needs some sort of conditional that checks that symlinks are available in Windows. "SYMLINK" used in the test file appears to be false even though I have developer mode enabled, allowing them.
I'd appreciate some feedback or pointers here; I've never submitted code to git.
Fixes #3358
ref pnpm/pnpm#4401