On Mon, Mar 28, 2022 at 8:38 PM Eric W. Biederman <ebiederm@xxxxxxxxxxxx> wrote: > > Dumb question because this seems to burning a few extra creativity > points. Is there any way to create a signed tag and a branch with the > same name? Oh, absolutely. But you may find it annoying, because as you noticed: > Having a tag and a branch with the same name seems to completely confuse > git and it just tells me no I won't push anything to another git tree, > because what you are asking me to do is ambiguous. Not at all. git is not at all confused by the situation, git is in fact very aware of it indeed. But as git then tells you, exactly *because* it is aware that you have picked the same name for both a branch and a tag, it will keep warning you about the ambiguity of said name (but after warning, will generally then preferentially use the tag of that name over the branch of the same name). So if you have both a branch and a tag named 'xyz', you generally need to disambiguate them when you use them. That will make git happy, because now it's not ambiguous any more. (Technical detail: some git operations work on specific namespaces, so "git branch -d xyz" should never remove a _tag_ called 'xyz', and as such the name isn't ambiguous in the context of that git command) And disambiguating them is simple, but I suspect you'll find it's annoying enough that you simply don't want to use the same name for tags and branches. The full name of a tag 'x' is actually 'refs/tags/x', and the full unambiguous name of a branch 'x' is 'refs/heads/x'. So technically a tag and a branch can never _really_ have the same name, because internally they have longer unambiguous names. You would almost never actually use that full name, it's mostly an internal git thing. Because even if you have ambiguous branch and tag names, you'd then still shorten it to just 'tags/x' and 'heads/x' respectively. Git has other "namespaces" for these refs, too, notably 'refs/remotes/'. In fact, I guess you could make up your own namespace too if you really wanted, although I don't think anybody really has ever had a good reason for it. (There is also the non-namespaced special refs like HEAD and FETCH_HEAD and MERGE_HEAD for "current branch", "what you fetched" and "what you are merging") So you *can* do this: # create and check out the branch 'xyz' $ git checkout -b xyz master # create a tag called 'xyz', but to confuse everybody, make it point somewhere else $ git tag xyz master~3 # look at what 'xyz' means: $ git rev-parse xyz warning: refname 'xyz' is ambiguous. cffb2b72d3ed47f5093d128bd44d9ce136b6b5af # Hmm. it warned about it being ambiguous $ git rev-parse heads/xyz 1930a6e739c4b4a654a69164dbe39e554d228915 # Ok, it clearly took the tag, not the branch: $ git rev-parse tags/xyz cffb2b72d3ed47f5093d128bd44d9ce136b6b5af so as you can see, yes, you can work with a tag and a branch that have the same 'short name', but having to disambiguate them all the time will likely just drive you mad. And it's worth pointing out that the name does not imply a relationship. So the branch called 'xyz' (ie refs/heads/xyz) has absolutely *no* relationship to the tag called 'xyz' (ie refs/tags/xyz) except for that ambiguous short name. So updating the branch - by perhaps committing more to it - will in no way affect the tag. Also note that branches and tags are both "just refs" as far as git is concerned, but git *does* give some semantic meaning to the namespaces. So the branch namespace (it those 'refs/heads/*' things) are things that get updated automatically as you make new commits. In contrast, the tag namespace is something you *can* update, but it's considered odd, and if you want to overwrite an existing tag you generally need to do something special (eg "git tag -f" to force overwriting a new tag rather than telling you that you already have one). So in a very real way, to git a ref is a ref is a ref, with very little to no real *technical* distinction. They are just ways to point to the SHA1 hash of an object. But there are basically some common semantic rules that are based on the namespaces, and all those git operations that use certain namespaces by default. Linus