Yes: An annotated tag object can point to another annotated tag object or even directly to a tree or blob. All this is quite rare.
The git rev-parse team is, indeed, Git as a whole; rev-parse is just a user interface for routines - it has the concept of "peeling" a tag or even committing to achieve a specific type of target. For example, if you want to view a tree attached to a commit or tag or hash id:
git rev-parse whatever^{tree}
turns the whatever part into everything that it is, and then tries to "expand" to the point where we get the tree object. If whatever is an annotated tag, this follows the tag to its object repeatedly until it reaches a non-tag, which by definition is either commit, tree, or blob:
- If we reached the tree, we are done.
- If we reach a commit, each commit has one top-level tree, so we retrieve that commit tree.
- If we reached blob, no tree was found, so the command (regardless of whether it is
git rev-parse or, for example, git diff or git diff-tree ) is missing.
Commands like git diff-tree that want <tree-ish> automatically turn any argument you pass into the tree, as if you added the suffix ^{tree} . As you would expect, the suffixes ^{commit} and ^{blob} also exist. There is also the suffix ^{tag} , which simply verifies that something is really a tag (since no other type of object can be allowed for the tag), and there is a suffix ^{} , which means "allow the tag for its object", those. remove all annotated tags, and then get any object.
Full rules are described in the gitrevisions documentation . Note that not every Git command behaves as described: in particular, git checkout tries to treat its argument as a branch name before following the six-step process in gitrevisions. This means that if the name foo can be either a tag or a branch, git checkout foo finds the branch (i.e. Checks refs/heads/foo ), but git show foo shows the result of resolving the tag.
torek source share