Git 中的简单参考与轻量级标签



我目前正在尝试了解 git 的内部;我的问题是轻量级标签和简单的 ref 有什么区别? 根据我目前所读到的内容,轻量级标签实际上是一个带有标签名称的文件,其内容是对象 ID [我猜是提交对象 ID?在这本书的"Git 袖珍指南"中,作者说">一个简单的引用直接指向一个对象 ID";这就是我困惑的地方!在我看来,这些是相同的东西,但命名不同。 说轻量级标签是简单引用的特定版本是否正确?因为轻量级标签只能指向提交对象,但简单引用不仅限于提交。

ref(或更长的变体,引用)是一个名称,在 Git 中。 引用有多种形式:

  • refs/heads/xyz分支名称xyz;
  • refs/tags/xyz是标签名称xyz;
  • refs/remotes/origin/xyz是您的 Git 用于名为xyz的分支的远程跟踪名称,如您origin调用的其他 Git 存储库中看到的那样;

等等。

Git 对象是以下四种对象类型之一:

  • blob 对象保存数据(例如,文件内容或符号链接的目标);
  • 树对象包含<模式、名称、哈希>元组,其中模式告诉您哈希指定的 Git 对象类型,并且名称包含名称组件(目录或文件名);
  • 提交对象保存提交的元数据,其中必须包含特定的标头(包括一个tree行,给出一个树对象的哈希 ID:这是提交的快照);
  • 标记对象
  • 带注释的标记对象包含标记数据,这些数据(如提交)必须包含特定的标头,包括提供标记对象的哈希 ID 的object行(可以是四种对象类型中的任何一种,包括另一个带注释的标记)。

所有对象都有一个唯一的哈希 ID。 此哈希 ID 充当简单键值数据库中的键。 Git 将使用密钥来查找对象;您必须提供密钥(以某种方式)。 如果您提供缩短的键(即键的前缀),Git 将查找该前缀找到的所有对象;如果只找到一个,则假定这是正确的完整哈希 ID,我们从那里继续;如果找到多个,我们有一个不明确的哈希 ID(可能是其中任何一个)。

所有引用都必须包含某个现有有效对象的哈希 ID。 某些对象还包含哈希 ID;这些也必须是某些现有有效对象的哈希 ID。1

某些引用在可能包含哪些对象类型方面受到限制:特别是,分支名称必须包含提交哈希 ID。 由于远程跟踪名称是通过从其他某个 Git 存储库读取分支名称(应遵守这组相同的约束)来创建的,因此远程跟踪名称还应包含提交哈希 ID。 但是,标记名称可以包含四种内部对象类型中的任何一种的哈希 ID。

轻量级标签refs/tags/*形式的引用(因此是标签名称),其中包含有效的哈希 ID,但用于不是标签对象的内部 Git 对象。带批注的标记是表单refs/tags/*的引用,其中包含作为带注释的标记对象的对象的有效哈希 ID。

说轻量级标签是简单引用的特定版本是否正确?

大多数情况下,是的。 轻量级标签是一个特定的 ref:以refs/tags开头的标签(然后是斜杠和更多名称字符)。 但是,它满足另一个约束:存储在该 ref中的哈希 ID 是类型不是"注释标签"的对象的哈希 ID。


1在所谓的浅克隆部分克隆中,此约束会稍微放松。 (您可以有一个既浅层又部分的克隆。 哈希 ID 应该是有效的,但在我们填写缺失的对象之前,我们无法判断它是否有效。

你是对的:轻量级标签一个简单的参考。

它的主要特点是它存储在.git/refs/tags下,这是一个约定,表明 git 命令可以将其视为标签:

  • git tag --list会列出来,
  • git tag -d <tag_name>将删除它,
  • git在某些情况下会将名称refs/tags/tag_name缩短为tag_name
  • 等。。。

与引用相关的其他主要约定是:

  • 分支存储在refs/heads
  • 远程
  • 引用(或远程分支)存储在refs/remotes/<remote_name>/

这些参考也是简单的参考。


非简单引用的一个示例是HEAD(存储在.git/HEAD中)。

您可以运行cat .git/HEAD来查看其内容:如果您当前在分支上,您应该看到类似以下内容:

$ cat .git/HEAD
ref: refs/heads/my_branch

这称为符号引用,作用于HEAD的命令(例如:git log HEAD)会将HEAD"翻译"为my_branch

最新更新