标签(tag)
Git 的标签用于给某个特定提交打上”快照”标记——通常用于版本发布(v1.0.0、v1.1.0 等)。
两种标签
| 类型 | 命令 | 是否含元数据 | 适用场景 |
|---|---|---|---|
| 轻量标签 | git tag <name> | 只指向某个 commit | 临时标记 |
| 附注标签 | git tag -a <name> -m "msg" | 含作者、日期、message | 正式发布版本(推荐) |
基础操作
$ git tag # 查看所有标签
$ git tag <name> # 在最新 commit 上打轻量标签
$ git tag <name> <commit-id> # 在指定 commit 上打轻量标签
$ git tag -a v1.0.0 -m "version 1.0.0" # 附注标签
$ git tag -d <name> # 删除本地标签
# 查看标签信息
$ git show v1.0.0
推送标签
$ git push origin <tagname> # 推送单个标签
$ git push origin --tags # 推送所有本地标签
$ git push origin :refs/tags/<tag> # 删除远程标签(Git < 1.7.10 旧语法)
Git 1.7.10 之后删除远程标签推荐用:
$ git push origin --delete <tagname>或先删本地再推空:
$ git tag -d v1.0.0 $ git push origin :refs/tags/v1.0.0
.gitignore 配置
.gitignore 文件告诉 Git 哪些文件不应该被跟踪——编译产物、IDE 配置、密钥文件等。
基本语法
# 注释以 # 开头
# 匹配所有 .log 文件
*.log
# 匹配所有 .tmp 文件
*.tmp
# 匹配 build 目录
build/
# 匹配 doc/notes.txt(精确路径)
doc/notes.txt
# 匹配 doc 目录下所有 .txt
doc/**/*.txt
# 否定:之前规则匹配的,这次不忽略
!important.log
# 字符匹配
file[0-9].txt
# 任意单层目录
temp/*.bak
通用 .gitignore 模板
跨语言推荐从 github/gitignore 选模板。常见组合:
# 操作系统
.DS_Store
Thumbs.db
# IDE
.idea/
.vscode/
*.swp
# Java
*.class
*.jar
*.war
target/
build/
# Node
node_modules/
dist/
.env
# Python
__pycache__/
*.pyc
.venv/
强制添加被忽略的文件
$ git add -f <file>
-f 强制 add,绕过 .gitignore 规则。场景:临时想提交一个被忽略的配置模板。
排查”为什么这个文件被忽略”
$ git check-ignore -v <file>
输出会告诉你哪条规则忽略了这个文件:
.gitignore:42:*.log <file>
已经误提交的文件怎么从跟踪列表移除
git rm 只能删除未跟踪文件被忽略——已经 commit 过的文件需要:
$ git rm --cached <file> # 从跟踪列表移除(工作区保留)
$ git rm -r --cached <dir> # 整个目录从跟踪列表移除
注意:必须
--cached才能保留工作区文件,否则git rm会连工作区一起删。
子模块(submodule)
子模块用于在一个 Git 仓库中嵌入另一个 Git 仓库——典型场景:
- 主项目引用公共库(公司内部 SDK)
- 文档站点引用独立仓库的文档源码
- 微服务架构中共享通用模块
添加子模块
$ git submodule add <repo-url> <path>
例如:
$ git submodule add https://github.com/spring-projects/spring-petclinic.git libs/petclinic
这会在仓库根目录创建 .gitmodules 文件,并 clone 子模块到 libs/petclinic。
.gitmodules 文件结构
[submodule "libs/petclinic"]
path = libs/petclinic
url = https://github.com/spring-projects/spring-petclinic.git
⚠️ 提交
.gitmodules而不是 URL 本身——它记录了子模块的来源信息。
clone 包含子模块的仓库
# 普通 clone 后再初始化
$ git clone <main-repo>
$ cd main-repo
$ git submodule init # 注册子模块路径
$ git submodule update # 实际下载子模块内容
# 一步到位
$ git clone --recursive <main-repo>
更新子模块
$ cd <submodule-path>
$ git pull # 拉取子模块最新代码
$ cd ..
$ git add <submodule-path> # 提交子模块引用更新
$ git commit -m "chore: 更新子模块"
移除子模块
$ git submodule deinit <path> # 反初始化
$ git rm <path> # 从跟踪列表移除
$ rm -rf .git/modules/<path> # 删除本地缓存
$ git commit -m "chore: 移除子模块 xxx"
子模块一旦加上后维护成本不低(嵌套仓库、引用更新、CI 配置),新项目优先考虑 Monorepo 工具(pnpm workspace、Nx、Turborepo)替代 submodule。
下一篇:Git 知识系列(六):仓库维护与排错,讲常见错误处理、.git 瘦身、远程分支切换、cherry-pick 与 bisect 等高级工具。