- 已经会基本提交和分支操作的开发者
- 想理解命令边界与风险的人
Command Reference
git tag 教程
介绍 git tag 如何标记发布点、轻量标签和附注标签的区别,以及标签推送的基本方式。
- 知道工作区、暂存区、提交的基本关系
- 能读懂 `git status` 和简单历史图
- 误把本地整理命令用到共享历史
- 在没确认恢复路径前直接继续改写历史
一句话理解
git tag 用来给某个提交打上稳定名字,最常见的场景是版本发布。
常见类型
- 轻量标签
- 附注标签
附注标签更适合正式发布,因为它包含更多元数据。
基本用法
git tag v1.0.0
git tag -a v1.0.0 -m "Release v1.0.0"
推送标签
git push origin v1.0.0
git push origin --tags
这条命令在流程里解决什么问题
git tag 作用于引用层,它给特定提交绑定一个稳定的名字。与分支不同,标签一旦创建通常不再移动,所以它解决的是"给历史中的某个点起永久名字"的问题,而不是日常开发中的工作流管理。
典型用例
- 给发布版本打标签(如
v1.0.0),让团队和 CI/CD 系统有一个明确的发布锚点。 - 附注标签(
-a)记录打标签的人和说明,适合正式发布流程。 - 轻量标签适合本地临时标记,不需要推送给团队。
图例理解
目标提交标签名称(附注时:作者/消息)
refs/tags/ 下的新引用(附注时:独立的 tag 对象)
标签不会自动推送到远端,需要显式 `git push origin <tag>` 或 `git push origin --tags`。
签名标签完整流程
对于正式发布,推荐使用签名标签(signed tag),它提供了身份验证和完整性保证。
GPG 密钥准备
# 生成 GPG 密钥(如果没有的话)
gpg --full-generate-key
# 按提示选择:RSA and RSA, 4096 位
# 查看密钥 ID
gpg --list-secret-keys --keyid-format long
# 输出类似:
# sec rsa4096/ABC123DEF4567890 2024-01-01 [SC]
# Your Name <you@example.com>
配置 Git 使用 GPG
# 告诉 Git 使用哪个 GPG 密钥
git config --global user.signingkey ABC123DEF4567890
# 或者让 Git 自动使用 user.email 对应的密钥
git config --global commit.gpgsign true
创建签名标签
# -s 参数创建签名标签
git tag -s v2.0.0 -m "Release v2.0.0"
# 验证标签签名
git tag -v v2.0.0
# 输出:
# object abc1234567890...
# type commit
# tag v2.0.0
# tagger Your Name <you@example.com> ...
#
# Release v2.0.0
# gpg: Signature made ... using RSA key ABC123DEF4567890
# gpg: Good signature from "Your Name <you@example.com>"
推送签名标签
# 单个推送
git push origin v2.0.0
# 批量推送所有标签
git push origin --tags
tag 推送策略
推送单个标签(推荐)
# 只推送新创建的标签,精确可控
git push origin v1.0.0
git push origin v1.1.0
优点:
- 精确控制推送了哪些标签
- 不会意外推送未准备好的标签
- 适合 CI/CD 流程中的自动化发布
推送所有标签
# 推送所有本地标签到远端
git push origin --tags
使用场景:
- 批量同步多个标签
- 团队统一约定标签管理规范时
- 新成员初始化环境时同步所有历史标签
风险:
- 可能推送测试/实验标签到生产远端
- 如果本地有不该推送的标签,会一起推上去
默认行为
git push 默认不会推送标签:
git push origin main
# 只会推送 main 分支,不包含任何标签
这是 Git 的安全设计,防止意外发布标签。
自动推送标签(可选配置)
# 配置 push 时自动推送匹配的标签
git config --global push.followTags true
开启后,git push 会自动推送与本次推送的 commit 关联的标签。
轻量标签 vs 附注标签对比
| 维度 | 轻量标签 (Lightweight) | 附注标签 (Annotated) |
|---|---|---|
| 创建命令 | git tag v1.0.0 | git tag -a v1.0.0 -m "msg" |
| Git 对象 | 只是一个引用指针 | 独立的 tag 对象 |
| 元数据 | 无 | 包含 tagger、日期、消息 |
| 签名支持 | ❌ 不支持 | ✅ 支持 (-s) |
| 存储位置 | refs/tags/v1.0.0 | refs/tags/v1.0.0 + tag 对象 |
git show 输出 | 显示 commit 信息 | 显示 tag 信息 + commit 信息 |
| 适用场景 | 本地临时标记、个人使用 | 正式发布、团队协作 |
| 是否推荐用于发布 | ❌ 不推荐 | ✅ 强烈推荐 |
直观对比
# 轻量标签
git tag v1.0-beta
git show v1.0-beta
# 输出直接显示 commit 内容
# 附注标签
git tag -a v1.0.0 -m "Release v1.0.0"
git show v1.0.0
# 输出先显示 tag 元数据,再显示 commit 内容
# tag v1.0.0
# Tagger: Name <email>
# Date: ...
#
# Release v1.0.0
tag 命名惯例
SemVer(语义化版本)
最主流的命名方式,格式:主版本.次版本.补丁版本
v1.0.0 ← 正式版
v1.0.1 ← 补丁修复
v1.1.0 ← 新功能
v2.0.0 ← 不兼容的大版本更新
Pre-release(预发布)
在正式发布前的测试版本:
v1.0.0-alpha.1 ← 内部测试版
v1.0.0-alpha.2
v1.0.0-beta.1 ← 公测版
v1.0.0-beta.2
v1.0.0-rc.1 ← 候选发布版
v1.0.0-rc.2
v1.0.0 ← 最终正式版
日期标签
适合频繁发布的场景:
release-2024-01-15
release-20240115
2024.01.15
命名建议
- 始终加
v前缀:v1.0.0比1.0.0更清晰 - 避免空格和特殊字符:
/、:等可能在远端有问题 - 保持一致性:团队统一命名规范
- 不要用标签名覆盖已有标签:即使使用
-f也不推荐
删除标签
删除本地标签
git tag -d v1.0.0
# Deleted tag 'v1.0.0' (was abc1234)
删除远端标签
# 方法 1:使用 --delete
git push origin --delete v1.0.0
# 方法 2:推送空引用(传统方式)
git push origin :refs/tags/v1.0.0
批量删除
# 删除所有本地预发布标签
git tag -l | grep -E 'alpha|beta|rc' | xargs git tag -d
# 同步删除远端对应标签
git tag -l | grep -E 'alpha|beta|rc' | xargs -I {} git push origin --delete {}
删除后的注意事项
- 删除远端标签后,其他协作者可能需要
git fetch --prune --prune-tags来清理本地缓存 - 已经下载的 tag 不会因为远端删除而自动消失
- 建议在删除前确认标签没有被 CI/CD 系统引用
特殊情况与边界
- 标签名和分支名在同一个命名空间里冲突时会有歧义,所以命名时要有区分度。
- 标签默认只在本地创建,不会随
git push自动同步到远端。 - 轻量标签只是一个引用指针,附注标签则是包含元数据的完整对象——发布时应优先使用附注标签。
- 给已经打标签的提交改名需要
-f强制覆盖,但谨慎操作以免误导协作者。