Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do git tags apply to all branches?

I'm getting my feet wet with git tagging, but my previous background is in Subversion, where "tags" were really just copies, not "real" tags...

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

For example, if I currently have these branches (git branch -v):

* master deadbeef My master head comment
  dev    baddfeed My def head comment

And the currently checked out branch is master, as you can see. Now suppose I git tag -a TAGNAME, does TAGNAME apply only to deadbeef (master branch) or to baddfeed (dev branch) as well?

e.g., Say I subsequently switch to the dev branch (i.e., not the branch the tag was created on) before checking out the tag:

git checkout dev
git checkout TAGNAME

Do I then end up with a checkout of baddfeed or will the tag checkout (second line) switch me back to the master branch (where the tag was created) and give me a checkout of deadbeef? (Or third option, is my understanding of creating and restoring tags too flawed or too simplistic for the answer to be as simple as one of those two options?)

Also, does the answer to my question change any if I use a lightweight tag (git tag TAGNAME) instead of an annotated tag?

like image 690
Dave Lillethun Avatar asked Aug 06 '13 18:08

Dave Lillethun


People also ask

Are git tags per branch?

As you can see, there's nothing tying those tags to any branches; in fact, all of those tags are contained in both the master and devel branches. By looking inside your . git repo, you can see that there is really no more structure to a tag than that; it is just a file containing a SHA-1 referencing a commit within .

How do tags work in git?

Git Tags are specific reference points in the Git history. Git tags are used to capture the specific point in the history that is further used to point to a released version. A tag does not change like a branch. They don't have a further history of commits after being created.

Are tags and branches the same?

The difference between tags and branches are that a branch always points to the top of a development line and will change when a new commit is pushed whereas a tag will not change. Thus tags are more useful to "tag" a specific version and the tag will then always stay on that version and usually not be changed.

Can you tag branches?

In order to create a Git tag for the last commit of your current checked out branch, use the “git tag” command with the tag name and specify “HEAD” as the commit to create the tag from. Similarly, if you want your tag to be annotated, you can still use the “-a” and “-m” options to annotate your tag.


3 Answers

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.

like image 74
Jean Waghetti Avatar answered Oct 29 '22 09:10

Jean Waghetti


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.

like image 38
torek Avatar answered Oct 29 '22 09:10

torek


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

like image 25
CodeWizard Avatar answered Oct 29 '22 11:10

CodeWizard