在大屏或电脑上体验更佳——动画和操作区域更宽敞。
输入

标签与发布

Git 标签给选定对象一个版本名,分支可以继续开发。标签是 Git 引用,附注标签还包含一个标签对象。托管平台的发布记录位于 Git 之外,与标签关联。本课发布登记表还会保存发布时剥离标签得到的提交,作为来源快照。

main 像持续装货的推车位置,提交让它前进;标签像贴在指定货箱上的名称,普通提交不移动它,但 -f 可以将同名标签改贴到别处。本课发布记录保存当时使用的货箱 ID。

分支自动前进,标签不会

分支和标签引用都保存对象 ID。区别不是“分支可变,标签不可变”,而是 HEAD 附着某分支时,commit 自动推进该分支,不推进原末端上的标签。标签只在明确重写引用的命令下移动。

轻量标签直接在 refs/tags/<name> 保存对象 ID,若目标是提交,剥离即可到达它。

附注标签在引用与提交之间增加对象。本课标签对象包含 object 行、type commit、标签名、tagger 身份、消息;引用保存标签对象的 ID。v1.0.0^{} 先沿引用到标签对象,再沿 object 到提交。标签对象按内容寻址,但引用仍可改写。

托管发布不是 Git 对象,标题、资源、草稿状态等保存在平台数据库。不同平台不一定像本课这样保留来源快照。GitHub 发布 API 用 tag_name 关联发布,target_commitish 在需要创建标签时生效,不代表已有标签的统一发布时提交快照。GitLab 发布 API 也以 tag_name 为中心,需要创建标签时使用 ref。本课记录剥离提交是为了展示来源变化,不是对各平台的承诺。

git switch --detach v1.0.0 同样剥离标签,然后将提交 ID 直接写入 HEAD。HEAD 不再命名 main;此时提交只推进分离 HEAD,分支和标签都不动。

标签与发布逐步演示

默认使用固定空树上的 allow-empty 提交,以观察引用。

  1. 起始 HEAD -> main,main 尚未诞生,没有提交、标签或发布记录。
  2. git commit --allow-empty -m "release-candidate" 创建无父根提交 C1,对象存在后才把 main 指向 C1。
  3. git tag -a v1.0.0 -m "First stable" 解析 HEAD 为 C1,创建 object 指向 C1 的附注标签对象,再将 refs/tags/v1.0.0 指向该对象。剥离得到 C1。
  4. Publish hosted release from v1.0.0 剥离到 C1,在本课登记表保存标题 VizLearn 1.0.0、资源 vizlearn-1.0.0.zip 和来源 C1,不写 Git 对象或引用。
  5. git commit --allow-empty -m "next-work" 创建 C2,只推进 main。此时 main 指 C2,标签和本课发布来源仍在 C1。
  6. git switch --detach v1.0.0 回到 C1,HEAD 从符号 main 改为直接提交。最终 main→C2,标签→附注对象→C1,发布来源→C1,HEAD→C1(分离)。

分支前进了,版本标签和发布记录仍标记原提交;按标签检查原版本,不会回移 main。

版本名称不等于来源证据

若发布只保留字符串 v1.0.0,之后有人在 C2 执行 git tag -f -a v1.0.0 ...,名称会解析到 C2,而既有 ZIP 可能来自 C1。

强制移动预设中,本课登记表保留 C1,所以能同时显示“发布来源 C1”和“当前标签 C2”。不一致只会提示,不自动修复。Git 允许明确的引用改写,真实平台能保留哪些历史证据取决于其数据模型。

检查发布来源

比较分支末端、剥离提交和标签对象:

git rev-parse refs/heads/main
git rev-parse 'v1.0.0^{}'
git cat-file -t v1.0.0
git cat-file -p v1.0.0

附注标签的 git cat-file -t 返回 tag,-p 展示其目标;轻量标签显示目标对象类型。再与 CI 记录的构建 SHA 比较,并对产物执行 shasum -a 256 vizlearn-1.0.0.zip 等哈希计算,把摘要与发布放在一起。标签名给出名称,提交 ID 和产物摘要记录构建与交付的具体内容。

边界情况

  • 未诞生 HEAD 没有对象,无法创建标签。
  • 已有同名标签且不加 -f,在创建新附注对象和改写引用前失败。
  • 标签缺失时发布和分离检出都失败,不创造虚假引用或发布。
  • 本课登记表每个标签名只允许一个发布,重复发布保留原记录。
  • 标签检出后再提交,只推进 HEAD,main、标签、发布来源不变。
  • 强制更新标签可改目标;已有发布时,应比较原来源、当前剥离提交及产物摘要。

常见错误

  • 说标签不可变。不可变的是按内容寻址的标签对象,标签引用可重写;普通提交只是不自动推进它。
  • 假设每个平台发布时都保存剥离提交。应查平台 API 和 CI 记录。
  • 把发布页和下载资源当 Git 对象。Git 保存提交、树、blob、附注标签对象,平台元数据另存。
  • 认为检出标签后 HEAD 附着标签。Git 剥离到提交并分离 HEAD。
  • 发布动作指定标签,却从当前 main 构建。应解析所选标签,main 可能已前进。
  • 强移已发布版本名后不比 ID 与摘要,同一名称可能已对应两次不同构建。

模型范围

本课只有一个分支、固定空树上的 allow-empty 提交、直接指向提交的附注对象。省略签名标签、嵌套标签、传输、打包引用、锁、reflog、钩子、CI 执行、校验和与 SBOM 存储、认证、草稿与预发布、下载量、平台特有行为。ID 使用 SHA-1 格式,SHA-256 仓库使用另一哈希。登记表保存剥离快照是为展示来源偏离,不是完整模拟 GitHub 或 GitLab。