简体   繁体   中英

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 <foo@bar.com>
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?

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 ).

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM