git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] refs: work around network caching on Windows

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Jul 15, 2022, 08:06 UTC
Message-ID
<pull.1291.git.1657872416216.gitgitgadget@gmail.com>
From: Pierre Garnier <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 https://github.com/git-for-windows/git/issues/3727
Signed-off-by: Pierre Garnier <pgarnier@mega.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
    refs: work around network caching on Windows
    
    While it is enough on Linux to look at ENOENT when allowing for missing
    refs, on Windows we also need to allow ENOTDIR.
    
    This fixes https://github.com/git-for-windows/git/issues/3727
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1291%2Fdscho%2Fenotdir-and-enoent-can-indicate-missing-refs-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1291/dscho/enotdir-and-enoent-can-indicate-missing-refs-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1291
 refs/files-backend.c  | 2 +-
 refs/packed-backend.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 8db7882aacb..b2a880f62f0 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -381,7 +381,7 @@ stat_ref:
 	if (lstat(path, &st) < 0) {
 		int ignore_errno;
 		myerr = errno;
-		if (myerr != ENOENT || skip_packed_refs)
+		if ((myerr != ENOENT && myerr != ENOTDIR) || skip_packed_refs)
 			goto out;
 		if (refs_read_raw_ref(refs->packed_ref_store, refname, oid,
 				      referent, type, &ignore_errno)) {
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 97b68377673..23d478627a7 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -480,7 +480,7 @@ static int load_contents(struct snapshot *snapshot)
 
 	fd = open(snapshot->refs->path, O_RDONLY);
 	if (fd < 0) {
-		if (errno == ENOENT) {
+		if (errno == ENOENT || errno == ENOTDIR) {
 			/*
 			 * This is OK; it just means that no
 			 * "packed-refs" file has been written yet,

base-commit: bbea4dcf42b28eb7ce64a6306cdde875ae5d09ca
-- 
gitgitgadget
Next: Eric Sunshine
Message 1 of 9 in “refs: work around network caching on Windows”
  1. refs: work around network caching on WindowsJohannes Schindelin via GitGitGadget, Jul 15, 2022
  2. Eric SunshineJul 15, 2022
  3. Johannes SchindelinJul 15, 2022
  4. Junio C HamanoJul 15, 2022
  5. Ævar Arnfjörð BjarmasonJul 15, 2022
  6. lstat(mingw): correctly detect ENOTDIR scenariosJohannes Schindelin via GitGitGadget, Jul 28, 2022
  7. Junio C HamanoJul 28, 2022
  8. Eric SunshineJul 28, 2022
  9. lstat(mingw): correctly detect ENOTDIR scenariosJohannes Schindelin via GitGitGadget, Jul 29, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.