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
Error at tag creation over local network when name includes directory "{dir}/{name}" : cannot lock ref #3727
Comments
First of all, could you verify that |
Hi, If I do this just after the error it does not return a line for test_dir.
After the first try, the directory is immediately visible in the file explorer. |
Wait, Explorer sees the update immediately, but |
What we experimented is that explorer sees the update immediately and git complains with this message : "cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory". Does it means that git does not see the directory immediately or it is another problem ... I can't say. It's a supposition. Could it comes from the API used by Git ? |
The answer to that question would still be quite useful.
You could build a custom Git for Windows where you instrument the code that produces that error message to find out in more detail what is going on. The culprit might be that something like
Are you saying that running |
I'll try to be clearer by illustrating with a script and the output. The script (batch file test.bat executed in the CMD terminal) :
The output :
|
Okay. I fear that the only way to diagnose this better is the approach I detailed above where you rebuild Git after instrumenting it with debug printf statements. |
Yes, that looks correct.
The most promising path forward would be to follow the code path into |
Hello, Before each test I delete the existing tags and tags directories. By adding a FindFirstFileW before GetFileAttributesExW in mingw.c , the tag creates without git complaining.
If I don't do the FindFirstFileW, I have the error
If I try to FindFirstFileW with ".", ".git/refs/tags" or ".git/refs/tags/test100", it fails. Anyone having any idea ? Thank you |
Hi ! After instrumenting in many ways to understand the code and particularly mingw_lstat and has_valid_directory_prefix (in mingw.c), I tried to instrument and debug then write my version of mingw_mkdir. Finally, I am wondering if the modification to do is to adapt the lstat error management in files_read_raw_ref ? If I replace Line 385 in 158a30d
in my use case, it seems to fix the problem. But I don't know the possible drawbacks or regression of this change... |
Hello, I don't know what to do with the result of my analysis. My conclusion is that the following line consider that any error different from ENOENT leads to the error that I experiment : Line 385 in 158a30d
whereas ENOENT is caught by the caller : Lines 640 to 642 in 158a30d
mingw_lstat seems to consider that ERROR_PATH_NOT_FOUND leeds to ENOTDIR when the parent directory exists in the path given in parameter (this is may case when I create a tag in the form "/") : Lines 1059 to 1063 in 158a30d
In the end, it could mean that ENOTDIR should be managed in the caller of lstat, that is to say files_read_raw_ref or lock_raw_ref. Do you agree ? Thank you. |
That sounds like a really good fix! Would you mind writing up the problem, the context, and the analysis in a commit message and then open a PullRequest? |
Yes, I will. |
@pgrmega thank you! |
This fix for the issue : git-for-windows#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.
This fix for the issue : git-for-windows#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.
Hello, For information... As I said in the description of the issue, the problem occurs only on our Windows Server 2019 VMs but not on the Windows Server 2012R2. We found that : http://woshub.com/slow-network-shared-folder-refresh-windows-server/. After applying those commands (that disable caches), the problem disappeared :
|
This fix for the issue : git-for-windows#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. Signed-off-by: Pierre Garnier <pgarnier@mega.com>
This fix for the issue : git-for-windows#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. Signed-off-by: GARNIER Pierre <pgarnier@mega.com>
This fix for the issue : git-for-windows#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. Signed-off-by: pgrmega <pgrmega@github.com>
This fix for the issue : git-for-windows#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. Signed-off-by: pgrmega <pgarnier@mega.com>
This fix for the issue : git-for-windows#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. Signed-off-by: pgrmega <pgarnier@mega.com>
This fix for the issue : git-for-windows#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. Signed-off-by: pgrmega <pgarnier@mega.com>
This fix for the issue : git-for-windows#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. Signed-off-by: pgrmega <pgarnier@mega.com>
Network shares sometimes use aggressive caching, in which case a just-created directory might not be immediately visible to Git. One symptom of this scenario is the following error: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen in all Windows setups. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ the following commands worked around it: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying culprit is that `GetFileAttributesExW()` that is called from `mingw_lstat()` can raise an error `ERROR_PATH_NOT_FOUND`, which is translated to `ENOTDIR`, as opposed to `ENOENT` as expected on Linux. Therefore, when trying to read a ref, let's allow `ENOTDIR` in addition to `ENOENT` to indicate that said ref is missing. This fixes git-for-windows#3727 Signed-off-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Network shares sometimes use aggressive caching, in which case a just-created directory might not be immediately visible to Git. One symptom of this scenario is the following error: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen in all Windows setups. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ the following commands worked around it: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying culprit is that `GetFileAttributesExW()` that is called from `mingw_lstat()` can raise an error `ERROR_PATH_NOT_FOUND`, which is translated to `ENOTDIR`, as opposed to `ENOENT` as expected on Linux. Therefore, when trying to read a ref, let's allow `ENOTDIR` in addition to `ENOENT` to indicate that said ref is missing. This fixes git-for-windows#3727 Signed-off-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Network shares sometimes use aggressive caching, in which case a just-created directory might not be immediately visible to Git. In such an instance, `GetFileAttributesW()` might return a value that `mingw_lstat()` currently mistakes for not indicating a directory. One symptom of this scenario is the following error: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen in all Windows setups. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ the following commands worked around it: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is not interpreted correctly, so that a perfectly fine leading directory is misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAtrtibutesW()` call correctly. This fixes git-for-windows#3727 Co-authored-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Network shares sometimes use aggressive caching, in which case a just-created directory might not be immediately visible to Git. In such an instance, `GetFileAttributesW()` might return a value that `mingw_lstat()` currently mistakes for not indicating a directory. One symptom of this scenario is the following error: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen in all Windows setups. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ the following commands worked around it: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is not interpreted correctly, so that a perfectly fine leading directory is misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAtrtibutesW()` call correctly. This fixes git-for-windows#3727 Co-authored-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Files' attributes can indicate more than just whether they are files or directories. It was reported in Git for Windows that on certain network shares, this let to a nasty problem trying to create tags: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen with all types of network shares. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ In the indicated instance, the following commands worked around the bug: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is interpreted as an enum value, not as a bit field, so that a perfectly fine leading directory can be misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAtrtibutesW()` call correctly. This fixes git-for-windows#3727 Reported-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Files' attributes can indicate more than just whether they are files or directories. It was reported in Git for Windows that on certain network shares, this let to a nasty problem trying to create tags: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen with all types of network shares. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ in the indicated instance the following commands worked around the bug: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is interpreted as an enum value, not as a bit field, so that a perfectly fine leading directory can be misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAtrtibutesW()` call correctly. This fixes git-for-windows#3727 Reported-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Files' attributes can indicate more than just whether they are files or directories. It was reported in Git for Windows that on certain network shares, this let to a nasty problem trying to create tags: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen with all types of network shares. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ in the indicated instance the following commands worked around the bug: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is interpreted as an enum value, not as a bit field, so that a perfectly fine leading directory can be misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAtrtibutesW()` call correctly. This fixes git-for-windows#3727 Reported-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Files' attributes can indicate more than just whether they are files or directories. It was reported in Git for Windows that on certain network shares, this led to a nasty problem trying to create tags: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen with all types of network shares. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ in the indicated instance the following commands worked around the bug: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is interpreted as an enum value, not as a bit field, so that a perfectly fine leading directory can be misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAtrtibutesW()` call correctly. This fixes git-for-windows#3727 Reported-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Files' attributes can indicate more than just whether they are files or directories. It was reported in Git for Windows that on certain network shares, this led to a nasty problem trying to create tags: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen with all types of network shares. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ in the indicated instance the following commands worked around the bug: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is interpreted as an enum value, not as a bit field, so that a perfectly fine leading directory can be misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAtrtibutesW()` call correctly. This fixes git-for-windows#3727 Reported-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
With certain network drives, [it was reported](git-for-windows/git#3727) that some attributes associated with caching confused Git for Windows. This [was fixed](git-for-windows/git#3753). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Files' attributes can indicate more than just whether they are files or directories. It was reported in Git for Windows that on certain network shares, this led to a nasty problem trying to create tags: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen with all types of network shares. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ in the indicated instance the following commands worked around the bug: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is interpreted as an enum value, not as a bit field, so that a perfectly fine leading directory can be misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAttributesW()` call correctly. This fixes git-for-windows#3727 Reported-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Files' attributes can indicate more than just whether they are files or directories. It was reported in Git for Windows that on certain network shares, this led to a nasty problem trying to create tags: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen with all types of network shares. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ in the indicated instance the following commands worked around the bug: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is interpreted as an enum value, not as a bit field, so that a perfectly fine leading directory can be misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAttributesW()` call correctly. This fixes #3727 Reported-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Files' attributes can indicate more than just whether they are files or directories. It was reported in Git for Windows that on certain network shares, this led to a nasty problem trying to create tags: $ git tag -a -m "automatic tag creation" test_dir/test_tag fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory Note: This does not necessarily happen with all types of network shares. One setup where it _did_ happen is a Windows Server 2019 VM, and as hinted in http://woshub.com/slow-network-shared-folder-refresh-windows-server/ in the indicated instance the following commands worked around the bug: Set-SmbClientConfiguration -DirectoryCacheLifetime 0 Set-SmbClientConfiguration -FileInfoCacheLifetime 0 Set-SmbClientConfiguration -FileNotFoundCacheLifetime 0 This would impact performance negatively, though, as it essentially turns off all caching, therefore we do not want to require users to do that just to be able to use Git on Windows. The underlying bug is in the code added in 4b0abd5 (mingw: let lstat() fail with errno == ENOTDIR when appropriate, 2016-01-26) that emulates the POSIX behavior where `lstat()` should return `ENOENT` if the file or directory simply does not exist but could be created, and `ENOTDIR` if there is no file or directory nor could there be because a leading path already exists and is not a directory. In that code, the return value of `GetFileAttributesW()` is interpreted as an enum value, not as a bit field, so that a perfectly fine leading directory can be misdetected as "not a directory". As a consequence, the `read_refs_internal()` function would return `ENOTDIR`, suggesting not only that the tag in the `git tag` invocation above does not exist, but that it cannot even be created. Let's fix the code so that it interprets the return value of the `GetFileAttributesW()` call correctly. This fixes #3727 Reported-by: Pierre Garnier <pgarnier@mega.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Setup
defaults?
to the issue you're seeing?
The git repository is not stored on the machine but accessed on a shared directory available into the local network.
The error does not occur on other machines accessing the same shared resource, it is to say the only thing is that we created new machines with a more recent OS (Windows Server 2012R2 => Windows Server 2019), all other things being equal.
The error does not occur with a repository locally stored on the machine hard drive.
The error occurs only for creation of a new tag including a directory : "{dir}/{name}".
It does not occurs if the directory already exists in the ".git\refs\tags".
It does not occurs if we create a tag not including a directory name : "{name}".
Details
We use PowerShell.
We tested on Bash/CMD/Powershell and have the same issue.
Minimal, Complete, and Verifiable example
this will help us understand the issue.
We expect the tag to be created.
An error : fatal: cannot lock ref 'refs/tags/test_dir/test_tag': unable to resolve reference 'refs/tags/test_dir/test_tag': Not a directory
URL to that repository to help us with testing?
It occurs with any repository.
The text was updated successfully, but these errors were encountered: