`type commit` in an annotated tag in git

允我心安 提交于 2019-12-11 01:58:54

问题


Echoing an annotated tag in git with git cat-file -p <hash-of-tag> produces something like this:

object <sha1-hash>
type commit
tag 0.0.1
tagger My Name (...)

Description of tag

object points to a commit object in my case. type commit implies this mustn't be the case necessarily. Are there cases where annotated tags don't point to commits?


回答1:


Yes: an annotated tag object can point to another annotated tag object, or even directly to a tree or blob. These are all fairly rare though.

The git rev-parse command—really, Git in general; rev-parse is just the user oriented interface to the routines—has the notion of "peeling" a tag, or even a commit, to reach a particular target object type. For instance, if you want to view the tree attached to a commit or tag or hash ID:

git rev-parse whatever^{tree}

turns the whatever part into whatever it is, then attempts to "drill down" to the point where we get a tree object. If whatever is an annotated tag, this follows the tag to its object, repeatedly, until it arrives at a non-tag, which by definition is either a commit, tree, or blob:

  • If we've reached a tree, we are done.
  • If we've reached a commit, each commit has one top-level tree, so we extract that commit's tree.
  • If we've reached a blob, there is no tree to be found, so the command (whether that's git rev-parse or, e.g., git diff or git diff-tree) errors out.

Commands like git diff-tree that want a <tree-ish> automatically turn whatever argument you give them into the tree, as if you had added the ^{tree} suffix. As you might expect, there are also ^{commit} and ^{blob} suffixes. There is also a ^{tag} suffix, which simply verifies that something is indeed a tag (since no other object type can be resolved to a tag), and there is a ^{} suffix that means "resolve a tag to its object", i.e., peel off all annotated tags, then get whatever object remains.

The 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 both a tag and a branch, git checkout foo finds the branch (i.e., checks out refs/heads/foo), but git show foo shows the result of resolving the tag.




回答2:


Yes you can tag any git object by passing its hash or other way of referencing it to git tag.

In addition to a commit, a tree (the directory listing referenced in a commit), blob (the file contents that are referenced in a tree) or even a tag may also occur in a tag.



来源:https://stackoverflow.com/questions/43858778/type-commit-in-an-annotated-tag-in-git

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