Skip to content

Commit d708fb3

Browse files
pgrmegadscho
authored andcommitted
refs: work around network caching on Windows
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 #3727 Signed-off-by: Pierre Garnier <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 8c57cba commit d708fb3

File tree

2 files changed

+2
-2
lines changed

2 files changed

+2
-2
lines changed

refs/files-backend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ static int read_ref_internal(struct ref_store *ref_store, const char *refname,
381381
if (lstat(path, &st) < 0) {
382382
int ignore_errno;
383383
myerr = errno;
384-
if (myerr != ENOENT || skip_packed_refs)
384+
if ((myerr != ENOENT && myerr != ENOTDIR) || skip_packed_refs)
385385
goto out;
386386
if (refs_read_raw_ref(refs->packed_ref_store, refname, oid,
387387
referent, type, &ignore_errno)) {

refs/packed-backend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ static int load_contents(struct snapshot *snapshot)
480480

481481
fd = open(snapshot->refs->path, O_RDONLY);
482482
if (fd < 0) {
483-
if (errno == ENOENT) {
483+
if (errno == ENOENT || errno == ENOTDIR) {
484484
/*
485485
* This is OK; it just means that no
486486
* "packed-refs" file has been written yet,

0 commit comments

Comments
 (0)