fgalan
fgalan

Reputation: 12322

Cannot create tag in git repository

I have a local git repository and I'm working in a given branch (release/0.5.0)

$ git status
# On branch release/0.5.0
nothing to commit (working directory clean)

which last commit (HEAD) is

$ git log -n 1
commit b24830d8e4df3d3d2553e0422c411fc00d30fe35
Author: foo <[email protected]>
Date:   Thu Feb 26 17:55:35 2015 +0100

    ADD Step: 0.4.1-next -> 0.5.0

and I have a tag named 0.5.0 (among others)

$ git tag
0.4.1/KO
0.5.0

which points to the aforementioned last commit in my branch

$ git rev-list 0.5.0 | head -n 1
b24830d8e4df3d3d2553e0422c411fc00d30fe35

I would like to create a second tag with name 0.5.0/KO pointing to the same commit (I'm assuming that git hasn't problems in having N tags pointing to the same commit). However, I get an error:

$ git tag 0.5.0/KO
error: unable to resolve reference refs/tags/0.5.0/KO: Not a directory
fatal: refs/tags/0.5.0/KO: cannot lock the ref

Maybe this is due to the name of the new tag stars with the name of an existing tag (the one named 0.5.0) plus "/"? Any help on how could I do this operation?

Upvotes: 1

Views: 2135

Answers (2)

VonC
VonC

Reputation: 1329692

For the record, you can get the same error message on Windows using a samba share.

That is why Git 2.37.3 (Q3 2022) fixes lstat() emulation on Windows, to mitigate that.

See commit 82ba119 (29 Jul 2022) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit 6c5fbd8, 08 Aug 2022)

lstat(mingw): correctly detect ENOTDIR scenarios

Reported-by: Pierre Garnier
Signed-off-by: Johannes Schindelin

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, Git v2.8.0-rc0 -- merge listed in batch #7) 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(man) 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 issue 3727.

Upvotes: 0

mipadi
mipadi

Reputation: 411340

refs/tags/0.5.0 already exists, but it is not a directory (it's a file), so Git can't create anything underneath it in the file tree, nor can Git create a directory named refs/tags/0.5.0. You'll have to name your new tag something that doesn't include / (such as 0.5.0-KO).

Upvotes: 2

Related Questions