forked from git/git
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fix problem where clone adds core.worktree due to path case differences #2731
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
Merged
dscho
merged 1 commit into
git-for-windows:main
from
SyntevoAlex:#0312(win)_clone_adds_worktree
Jul 3, 2020
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
So is it this function call that is failing, or the
GetFinalPathNameByHandleW()
one?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.
It's
CreateFile()
that fails.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.
Of course, because of the
OPEN_EXISTING
flag.So here would be a splendid spot to insert
if (h == INVALID_HANDLE_VALUE && GetLastError()) ...
. The easiest way would actually to look for the last path separator in bothpath
andwpath
; That way, you do not have to duplicate the last component, but can trim thewpath
and by storing its position withinpath
in a new local variable (that can be initialized to ""), you can then append it after thexwcstoutf()
call below (actually after verifying that that call worked successfully).That's not a ton more code, actually. Essentially something like this:
And then later
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.
It seems that the core question here is whether to narrow retrying to
FILE_NOT_FOUND
or not. Previously I already shown that withFILE_NOT_FOUND
only,mingw_strbuf_realpath()
may fail wherestrbuf_realpath()
does not, which could again invite issues like the PR is trying to solve. Just to remind,core.worktree
problem begins whenmingw_strbuf_realpath()
fails andstrbuf_realpath()
succeeds.I would say that
mingw_strbuf_realpath()
shall never fail wherestrbuf_realpath()
succeeds.Now, what other errors could happen? For instance,
xutftowcs_path_ex()
may fail, because the last component is too long. Again,strbuf_realpath()
will probably succeed here, and my design will succeed, but your design will fail and fall back tostrbuf_realpath()
. It's a bit hard to really judge if this is a good or bad thing, but again, I would rather prefer to stay closer tostrbuf_realpath()
.It's a bit hard to predict which design may have more unexpected problems in it. Most of this comes from the difference between
lstat()
(used in originalstrbuf_realpath()
) andCreateFile()
, where the first is more forgiving - it can tolerate things like no-access folders and broken symlinks.If we agree to retry on all errors, then I'm not sure if your design is better. It's roughly the same amount of code, but it's harder to follow, as it has more parallel things to keep in mind while reading. For example, simultaneously removing (in different ways) the last component from two strings instills doubt and takes an extra read to verify. In my design, I think it's easier to grasp the second function once the first one is understood. It it's not about code clarity, then the other possible reason is performance. Performance-wise, the only difference is that my design will execute an extra
xutftowcs_path_ex()
, and your design will instead search for last component inwchar*
. That's probably a very small difference compared to cost ofCreateFile()
.To summarize, if you're confident and want your way, say so and I will implement.
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.
A different observation: I'm suspecting that the root cause is even deeper. To my understanding, you implemented
mingw_strbuf_realpath()
to solve problem with junctions. During my debugging adventures, I noticed thatfile_attr_to_st_mode()
does not recognize junctions asS_IFLNK
. That definitely raised my eyebrow.Could it be that entire
mingw_strbuf_realpath()
needs to be removed again, andfile_attr_to_st_mode()
fixed so thatstrbuf_realpath()
works as intended? That will put an end to all cases wheremingw_strbuf_realpath()
andstrbuf_realpath()
disagree.Afterall, I have a bad gut feeling about two different
strbuf_realpath()
implementations, which are prone to disagreeing because they use quite different APIs.What do you think?
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.
Yes, that is intentional. see e.g. the discussion in #437.
I guess so.
And if
mingw_strbuf_realpath()
fails, that's okay, because it then returnsNULL
andstrbuf_realpath()
continues with the non-Windows-specific code. Remember,mingw_strbuf_realpath()
is not a replacement ofstrbuf_realpath()
, it is a potential shortcut called by the latter.Sure, but the changes I proposed fix that, too. And their scope is so narrow that I am relatively confident that no unintended side effects are introduced. Retrying on all errors, on the other hand, does strike me as asking for unintended side effects.
That was not the intention when I introduced the former as a potential shortcut by calling it from the latter.
Yes, but I also used the opportunity to use native Win32 API to resolve symlinks rather than doing it (tediously) "by hand".
Not really:
vs
I find it harder to follow the two-function version, actually, especially because the return value type was changed (which was unnecessary) and because it is so unclear in the two-function version whether we are retrying for a legitimate reason or not.
First of all, they are not different implementations. One function calls the latter (a platform-specific shortcut, where available).
And the only reason why they use different APIs is because
strbuf_realpath()
can only rely on a subset of POSIX functionality, and therefore cannot use platform-specific functions. That's whyplatform_strbuf_realpath
is a thing, to abstract that away from the generic implementation.I do agree, however, that it is really tricky to navigate all of the issues with junction points vs symlinks. Which is the reason why I want to stay away from making sweeping changes as much as I can, and use more surgical ways to address the issue you found.
I pushed my proposed
fixup!
to my fork (under the same branch name you chose, to make it easier for you) and the test suite is currently running: https://github.com/dscho/git/runs/833879717?check_suite_focus=true.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 for taking time to prepare a fixup! It looks reasonable to me, and I squashed it as is.