Skip to content
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

Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes #3753

Merged
merged 1 commit into from
Jul 29, 2022

Conversation

pgrmega
Copy link

@pgrmega pgrmega commented Mar 24, 2022

This fix for the issue : #3727

Use case :
Creation of a tag in the form "parent/child".

Exemple :

git tag -a -m "my message" tagdir/mytag

Context :
$ git --version --build-options
git version 2.35.1.windows.2
cpu: x86_64
built from commit: 5437f0f
sizeof-long: 4
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon
$ cmd.exe /c ver
Microsoft Windows [Version 10.0.17763.2565]

Error :
fatal: cannot lock ref 'refs/tags/tagdir/mytag': unable to resolve reference 'refs/tags/tagdir/mytag': Not a directory

Problem analysis:
GetFileAttributesExW used in mingw_lstat function in git/compat/mingw.c can raise an error ERROR_PATH_NOT_FOUND.
In this case, the has_valid_directory_prefix is used to check if the parent directory exists.
So that, when the parent directory exists, mingw_lstat returns ENOTDIR.
ENOTDIR is not managed by the caller code (files_read_raw_ref in git/refs/files-backend.c).
It probably should.

Conclusion
This commit enables to take into account the case when ENOTDIR is returned by mingw_lstat.

Copy link

@hazmee007 hazmee007 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

แก้ไขข้อผิดพลาด "ร้ายแรง: ไม่สามารถล็อคการอ้างอิง ... ไม่ใช่ไดเรกทอรี"

(English: Fixes "Serious: References cannot be locked ... not directories" error. )

@dscho
Copy link
Member

dscho commented Apr 4, 2022

@pgrmega this looks good! Could you still sign off the patch to allow me to upstream this to the Git project?

@pgrmega
Copy link
Author

pgrmega commented Apr 5, 2022

I amended the commit to add signed-off.

@pgrmega pgrmega force-pushed the patch-2 branch 6 times, most recently from b7095f3 to 7d8a8f8 Compare April 8, 2022 09:39
@pgrmega
Copy link
Author

pgrmega commented Apr 12, 2022

Hello @dscho ,
I don't know how to manage this situation.

@dscho
Copy link
Member

dscho commented Apr 21, 2022

From https://github.com/git-for-windows/git/runs/5883049437?check_suite_focus=true#step:5:1163:

+ git init my_submodule
fatal: not a git repository: /home/runner/work/git/git/t/trash directory.t2501-cwd-empty/my_submodule/../.git/modules/my_submodule
error: last command exited with $?=128

I guess that there is code that actually relies on errno == ENOTDIR causing read_refs_internal() to return with an error.

Do you have access to a WSL setup? You could debug this issue in there, as it obviously does not reproduce on Windows itself.

@dscho
Copy link
Member

dscho commented May 13, 2022

Do you have access to a WSL setup?

@pgrmega do you?

@pgrmega
Copy link
Author

pgrmega commented May 13, 2022

Do you have access to a WSL setup?

@pgrmega do you?

Hello, sorry, no, I hadn't have the time to search how to debug in a linux environment.

@dscho
Copy link
Member

dscho commented May 14, 2022

@dscho dscho changed the title Fix error "fatal: cannot lock ref ... Not a directory" Work around lazy caching of network shares when directories were just created Jul 14, 2022
@dscho
Copy link
Member

dscho commented Jul 14, 2022

Do you have access to a WSL setup?

@pgrmega do you?

Hello, sorry, no, I hadn't have the time to search how to debug in a linux environment.

I finally got around to spend some time on this, and it turns out that you found the right spot to fix this, but there was another spot, too.

The way I debugged this was with one of the more tedious tools in my debugging toolbox:

int x = 0;

fprintf(stderr, "current pid: %d\n", (int)getpid());

while (!x) {
    sleep(1);
}

I inserted this at the code site you had touched, ran the test script t/t2501-cwd-empty.sh, attached a gdb to the process, and noticed that both with and without the new ENOTDIR treatment the process was erroring out, but the error message was different in both cases. Stopping at die_builtin() then pointed to the correct location for the second change that was required.

The load_contents() function is hit because we change read_ref_internal() to continue in case of ENOTDIR which means that refs_read_raw_ref() is called which eventually tries to create_snapshot().

@dscho
Copy link
Member

dscho commented Jul 15, 2022

FWIW I just submitted this patch to the Git mailing list for review: gitgitgadget#1291

@dscho
Copy link
Member

dscho commented Jul 15, 2022

@pgrmega could you test something for me? Could you apply this patch and tell me what it outputs when trying to tag?

diff --git a/compat/mingw.c b/compat/mingw.c
index 2607de93af5..5bac330e56e 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -768,6 +768,7 @@ static int has_valid_directory_prefix(wchar_t *wfilename)
 		wfilename[n] = L'\0';
 		attributes = GetFileAttributesW(wfilename);
 		wfilename[n] = c;
+error("attributes for '%ls': %ld, last error: %ld", wfilename, attributes, GetLastError());
 		if (attributes == FILE_ATTRIBUTE_DIRECTORY ||
 				attributes == FILE_ATTRIBUTE_DEVICE)
 			return 1;

The problem I am trying to figure out is why we run into this code path, where Git thinks that there is a non-directory in the way, but there actually isn't.

@dscho
Copy link
Member

dscho commented Jul 15, 2022

@pgrmega while I am still very interested in the output I asked for, I now have a hunch that I might have found the real fix. Could you also test this patch (replacing the one adding the || myerr == ENOTDIR part)?

diff --git a/compat/mingw.c b/compat/mingw.c
index 2607de93af5..2678302c6a9 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -768,8 +768,8 @@ static int has_valid_directory_prefix(wchar_t *wfilename)
 		wfilename[n] = L'\0';
 		attributes = GetFileAttributesW(wfilename);
 		wfilename[n] = c;
-		if (attributes == FILE_ATTRIBUTE_DIRECTORY ||
-				attributes == FILE_ATTRIBUTE_DEVICE)
+		if (attributes & (FILE_ATTRIBUTE_DIRECTORY |
+				  attributes == FILE_ATTRIBUTE_DEVICE))
 			return 1;
 		if (attributes == INVALID_FILE_ATTRIBUTES)
 			switch (GetLastError()) {

@rimrul
Copy link
Member

rimrul commented Jul 16, 2022

+		if (attributes & (FILE_ATTRIBUTE_DIRECTORY |
+				  attributes == FILE_ATTRIBUTE_DEVICE))

This feels a little weird. Should this perhaps be something like this?

if (attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE))

@dscho
Copy link
Member

dscho commented Jul 16, 2022

+		if (attributes & (FILE_ATTRIBUTE_DIRECTORY |
+				  attributes == FILE_ATTRIBUTE_DEVICE))

This feels a little weird. Should this perhaps be something like this?

if (attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE))

D'oh. Of course! You're absolutely right, that's what I meant but failed to re-read properly when I tried to write it down.

@pgrmega
Copy link
Author

pgrmega commented Jul 19, 2022

@dscho, is this still usefull that I test your patch ?
If yes, I'll try to find time...

@pgrmega while I am still very interested in the output I asked for, I now have a hunch that I might have found the real fix. Could you also test this patch (replacing the one adding the || myerr == ENOTDIR part)?

diff --git a/compat/mingw.c b/compat/mingw.c
index 2607de93af5..2678302c6a9 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -768,8 +768,8 @@ static int has_valid_directory_prefix(wchar_t *wfilename)
 		wfilename[n] = L'\0';
 		attributes = GetFileAttributesW(wfilename);
 		wfilename[n] = c;
-		if (attributes == FILE_ATTRIBUTE_DIRECTORY ||
-				attributes == FILE_ATTRIBUTE_DEVICE)
+		if (attributes & (FILE_ATTRIBUTE_DIRECTORY |
+				  attributes == FILE_ATTRIBUTE_DEVICE))
 			return 1;
 		if (attributes == INVALID_FILE_ATTRIBUTES)
 			switch (GetLastError()) {

@pgrmega
Copy link
Author

pgrmega commented Jul 19, 2022

@pgrmega while I am still very interested in the output I asked for, I now have a hunch that I might have found the real fix. Could you also test this patch (replacing the one adding the || myerr == ENOTDIR part)?

diff --git a/compat/mingw.c b/compat/mingw.c
index 2607de93af5..2678302c6a9 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -768,8 +768,8 @@ static int has_valid_directory_prefix(wchar_t *wfilename)
 		wfilename[n] = L'\0';
 		attributes = GetFileAttributesW(wfilename);
 		wfilename[n] = c;
-		if (attributes == FILE_ATTRIBUTE_DIRECTORY ||
-				attributes == FILE_ATTRIBUTE_DEVICE)
+		if (attributes & (FILE_ATTRIBUTE_DIRECTORY |
+				  attributes == FILE_ATTRIBUTE_DEVICE))
 			return 1;
 		if (attributes == INVALID_FILE_ATTRIBUTES)
 			switch (GetLastError()) {

@pgrmega pgrmega closed this Jul 19, 2022
@pgrmega pgrmega deleted the patch-2 branch July 19, 2022 16:04
@pgrmega pgrmega restored the patch-2 branch July 19, 2022 16:05
git-for-windows-ci pushed a commit that referenced this pull request Jul 29, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Jul 29, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 1, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 1, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 3, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 3, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
dscho added a commit that referenced this pull request Aug 5, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 5, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 5, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 5, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 5, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 5, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 6, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
dscho added a commit that referenced this pull request Aug 8, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 8, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 8, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
dscho added a commit that referenced this pull request Aug 9, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 10, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 10, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 10, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 11, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 11, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 11, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 11, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 11, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 11, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 12, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
dscho added a commit that referenced this pull request Aug 12, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
git-for-windows-ci pushed a commit that referenced this pull request Aug 14, 2022
Fix when lazy caching of network shares tags directories were just created with previously-unhandled attributes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants