Do git tags apply to all branches?

笑着哭i 提交于 2019-12-03 05:26:44

Let's say you are in branch myBranch. And you create a tag called myTag

-----A-----B-----C-----D-----H-------I-----> master
                       \
                        \
                         \---E----F-----G-----> myBranch
                                        |
                                        myTag

The tag will be only on the commit object of the myBranch branch. I've worked with CVS too, and it tags revisions too, not all branches (but in CVS branches are special tags). I don't think.

If you checkout myTag, you will be in the commit G of the example. You can't create tags with the same name on differente branches. If you do it, you will move the tag.

There's no difference for an annotated tag related to this.

Note: when checking out tags, you end up with "detached HEAD" mode. Your changes will be lost unless you create another branch starting from the tag checked out.

CodeWizard

To make it simple:

If I add a tag to a git repo, is it applied to all branches or only the current one?

In Git, a tag is simply an alias to a commit id. When you add a tag, Git simply maps your tag name (the tag string) to a given commit id. Since the commit id is relevant to a specific branch (or branches when merging) the tag will be relevant only to that branch (and to any it was merged into).

More info can be found here:

http://git-scm.com/book/en/Git-Basics-Tagging#Creating-Tags

Having read the questions and your comments, I think the basic point that is confusing you here is what it means in git (vs other systems) to be "on a branch".

In git, a git checkout operation checks out some particular commit [but see footnote 1]. It also sets the special name HEAD so that it refers to that particular commit. But: there are two different ways that HEAD can specify a particular commit. It can be:

  • by ID (this is the not-usual case), or
  • by indirect reference to a branch name (this is the more-usual case).

If you do git checkout branchname, git sets up the second, usual case. If you then cat .git/refs/HEAD you will find it contains the literal string ref: followed by refs/heads/branchname [2]. That's what it means to be "on the branch": you have checked out the commit that the branch-name refers to, but also, HEAD is a "symbolic ref". If you make new changes and commit them, git will make the new commit, then "peel off" the branch label sticky-note and paste it onto the new commit you just added. That "moves the branch" to the newly added tip, and you're "still on the branch".

On the other hand, if you do git checkout tagname, git sets up the first, unusual case. It does the same if you check out by SHA-1 ID (those ea56709... style strings). In this case, the file for HEAD just has the literal SHA-1 ID in it. In this state, if you make a new commit, it gets added as usual, but there's no sticky-note-changing to move branch labels around. You're not "on a branch"; HEAD is not a "symbolic ref".

As far as the actual tags themselves go, they are merely names for commits. But wait, isn't that what a branch name is? Yes! The difference between a branch name and a tag name is that a branch name is expected to move, and git will move it automatically in that "on a branch" case. A tag name is not "expected to move" [3] and will never move automatically.


Footnotes:

[1] Just to confuse things (or because git's user interface is "evil", as some would put it :-) ) there are cases when git checkout does not alter HEAD, specifically when you ask it to check out particular pathnames.

[2] In very old versions of git, instead of ref: ... git used a symbolic link. The target of the link was the branch ID-file, e.g., refs/heads/master or whatever, so opening and reading the file got the commit ID, and you had to use lstat to detect "on a branch". This does not work on Windows and precluded "packing" refs (.git/packed-refs), hence the change to use ref: instead.

[3] The phrases "is expected" and "is not expected" should prompt you to ask: expected by whom? Git itself is OK with git users moving tags, it's the people using git (and often, scripts they write) that get confused by this. So don't move a tag unless you've first checked with other people sharing the repository.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!