2

Does a git tag point to a specific sha1, a specific commit on a specific branch, or something else?

This question is extremely similar to What happen to Git tags pointing to a removed commit, but I am unable to find the answer I am looking for there.

Let's use the following example:

            C (Branch, cut with same commit history)
            |             
A-----B-----C (Main)

I'm trying to help myself answer the following questions:

  1. If I tag commit C on Main before cutting Branch, does my tag apply to Main and/or Branch?

  2. If I tag commit C on Main after cutting Branch, does my tag apply to both Main and/or Branch?

  3. If I tag commit C on Branch after cutting Branch, does my tag apply to both Main and/or Branch?

  4. What happens if there is a different commit history? For example, does anything change with the following:

                C-----D-----E (tag on E in either the main branch or this branch)
                |
    A-----B-----C-----E
    

edit: looks like #4 is impossible because a commit cannot have the same hash if the parent is different

Azianese
  • 554
  • 7
  • 21

3 Answers3

4

An ordinary tag is just a name for a specific Git object, which is usually a commit but can be a tree, a blob, or anything else with a hash.

An annotated tag is itself a distinct object that contains a reference to another object.

Regarding your questions:

  1. It applies to C. Main and Branch are currently just two other names for the same commit. But committing to either branch does not affect what the tag will refer to; it will remain a name of the commit C.

  2. Neither. The tag refers to C, not any of the branch heads that may also refer to C.

  3. Neither. It refers to C.

  4. The branch history doesn't really make sense. Your two Cs are distinct commits, as are your two Es. The tag would refer to exactly one of the two Es.

In short: tags are usually independent of branches.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • Does a tag ever point to just a single commit (a single revision of the code)? At that point, there would be no difference between a tag and a commit. I was under the assumption that a tag is for saving the state of the tree so that you can refer back to it when needed (for a rollout state for example). – Azianese Sep 18 '20 at 19:41
  • Also, I'm not understanding why my two C's or two E's must be separate commits in #4. C or E are just the names I've given for specific revisions and can be cut to a different branch or merged to a different branch. – Azianese Sep 18 '20 at 19:44
  • Why did you give them the same name? – chepner Sep 18 '20 at 19:49
  • 1
    A tag is just another way to *refer* to a commit. You can always refer to a commit by its hash, but those are hard to remember, so you create a tag to give you a more memorable name to use. – chepner Sep 18 '20 at 19:50
  • 1
    Also, *every* commit is a snapshot of the contents of a tree; a commit is little more than a reference to a parent commit along with a reference to a tree. – chepner Sep 18 '20 at 19:52
  • Thanks! Looks like my idea understanding of what a commit entails was a bit short (I thought a "commit" simply referred to a snapshot of changes made) and failed to consider that a commit also references a parent commit. Now it makes sense why E cannot be the same commit even if the same changes were made. And it also makes sense how a tag can point to the state of the commit tree even if it only directly points to a specific commit. Thanks for correcting my understanding – Azianese Sep 18 '20 at 20:03
  • 2
    All that said, it is probably fair to say that the most common use of a tag is to label a particular commit within a long-lived branch as a particular release. However, the [Pro Git book](https://git-scm.com/book/en/v2) gives an [example](https://git-scm.com/book/en/v2/Git-Internals-Git-References#_tags) of a tag referring to something other than a commit. – chepner Sep 18 '20 at 20:17
1

A branch is a commit pointer. A tag also points to a commit. That doesn't change if the commit is merged into a different branch.

isherwood
  • 58,414
  • 16
  • 114
  • 157
  • So by your definition that a tag points to a commit, then in #4 in my question, it sounds like the tag would apply to both Main and Branch as soon as I tag E in either Main or Branch. But in this post https://stackoverflow.com/questions/1457103/how-is-a-tag-different-from-a-branch-in-git-which-should-i-use-here they've defined tags as pointing to a version of a particular branch at a moment in time. And this other definition would lead to a different conclusion than the one I am led to believe with your answer – Azianese Sep 18 '20 at 19:30
  • At a moment in time, a branch is just a reference to the latest commit (the head). You have to not think of branches as things, but just aliases for a commit state. – isherwood Sep 18 '20 at 19:33
  • 2
    @Azianese the reason you're confused in #4 is because your example graph in #4 is impossible. E cannot possibly have the same commit ID (hash) if it has different parents. The fact that the top is coming off of D means it will be a different hash than the bottom. So you should call the top one F, or E' if you prefer. Then the tag can point to either E or E', but not both. – TTT Sep 18 '20 at 20:20
  • @TTT You're absolutely abright. My understanding of what a commit entails was lacking. chepner helped me understand this as well in a comment under his answer – Azianese Sep 18 '20 at 22:18
0

A branch is a pointer point to a commit.
A tag is also a pointer point to a commit, it has nothing to do with branch.
The difference is that a tag is immutable, it always point to the same commit. And the commit of branch will change when execute command git reset or git commit

Chuck Lu
  • 173
  • 12