name: version-control description: | Git版本控制的专家指导,主干开发工作流,以及GitHub最佳实践。 强调Conventional Commits以保持清晰的历史记录、短生命周期特性分支、频繁集成和专业的协作模式。适用于用户需要帮助处理git命令、分支策略、提交消息、PRs、合并冲突或git故障排除时。触发词包括’git’、‘commit’、‘branch’、‘merge’、‘rebase’、‘PR’、'pull request’或版本控制问题。 allowed-tools: “*”
版本控制与Git工作流技能
指导用户通过专业的版本控制实践,使用Git进行主干开发、Conventional Commits和GitHub集成。
核心理念
主干开发:
- 保持主分支始终可部署
- 短生命周期特性分支(几天,而非几周)
- 频繁集成到主分支
- 小的增量更改
- 持续集成思维方式
Conventional Commits:
- 结构化、语义化的提交消息
- 支持自动化工具(变更日志、版本控制)
- 历史记录中清晰的意图和范围
- 可搜索、可过滤的提交
GitHub集成:
- 代码审查的拉取请求
- 主分支的保护
- 使用GitHub Actions的CI/CD
- 清晰的PR描述和讨论
主干开发工作流
主分支
- 始终可部署 - 主分支应始终处于工作状态
- 受保护 - 需要PRs、审查、通过CI
- 事实来源 - 所有分支从主分支分出并合并回主分支
- 无长期分支 - 避免开发、暂存分支
特性分支工作流
1. 从主分支开始:
git checkout main
git pull origin main
git checkout -b feat/user-authentication
2. 进行小而专注的更改:
- 每个分支一个特性/修复
- 频繁提交,使用Conventional Commits
- 保持分支生命周期短(理想1-3天)
3. 保持同步:
# 频繁从主分支更新
git checkout main
git pull origin main
git checkout feat/user-authentication
git rebase main # 保持线性历史
4. 推送并创建PR:
git push -u origin feat/user-authentication
# 在GitHub上创建PR
5. PR批准后:
# 压缩合并或合并提交到主分支
# 立即删除特性分支
git checkout main
git pull origin main
git branch -d feat/user-authentication
分支命名约定
模式:<类型>/<简短描述>
类型匹配Conventional Commit类型:
feat/add-oauth-login- 新特性fix/authentication-timeout- 错误修复refactor/database-queries- 代码重构docs/api-endpoints- 文档test/user-service- 仅测试chore/update-dependencies- 维护
保持描述简短、小写、用连字符分隔。
Conventional Commits
格式
<类型>(<范围>): <主题>
<正文>
<页脚>
必需: 类型、主题 可选: 范围、正文、页脚
类型
feat: 用户的新特性
feat(auth): 添加OAuth2认证
fix: 错误修复
fix(api): 处理用户端点中的空响应
docs: 文档更改
docs(readme): 更新安装说明
style: 代码风格/格式化(无逻辑更改)
style(components): 修复Button中的缩进
refactor: 代码重构(无行为更改)
refactor(database): 提取查询构建器类
perf: 性能改进
perf(images): 实现懒加载
test: 添加或更新测试
test(auth): 添加登录流程的集成测试
build: 构建系统或依赖项
build(deps): 升级React到v18.2
ci: CI/CD配置
ci(github): 添加自动化部署工作流
chore: 维护任务
chore(deps): 更新开发依赖项
revert: 恢复之前的提交
revert: 恢复“feat(auth): 添加OAuth2认证”
范围
可选但推荐。指示代码库的哪部分更改:
feat(api):- API更改fix(ui):- UI修复refactor(database):- 数据库重构feat(auth):- 认证特性
使用对您的代码库有意义的项目特定范围。
主题规则
- 使用祈使语气:“添加”而非“已添加”或“添加了”
- 首字母不大写
- 结尾无句号
- 保持少于50个字符
- 完成句子:“如果应用,此提交将…”
好:
feat(api): 添加用户个人资料端点
fix(auth): 防止令牌过期竞态条件
差:
feat(api): 添加了用户个人资料端点。
fix(auth): 修复一个错误
更新东西
正文(可选)
- 解释什么和为什么,而非如何
- 每行72个字符换行
- 用空行与主题分隔
- 使用要点列出多个点
feat(search): 实现全文搜索
- 添加PostgreSQL全文搜索索引
- 创建带分页的搜索API端点
- 实现按相关性排序的搜索结果
这使用户能够跨所有内容搜索,性能优于之前的LIKE查询。
页脚(可选)
重大更改:
feat(api): 更改认证端点
重大更改: /auth/login 移动到 /api/v2/auth/login
问题引用:
fix(ui): 防止模态框在背景点击时关闭
修复 #123
关闭 #456
示例
简单特性:
feat(dashboard): 添加用户活动图表
带详细信息的错误修复:
fix(api): 处理网络超时错误
之前,网络超时会崩溃应用程序。
现在我们捕获超时错误并向客户端返回适当的错误响应。
修复 #789
重大更改:
feat(api)!: 重新设计用户认证
重大更改: 认证令牌现在1小时后过期,而非24小时。客户端必须实现令牌刷新逻辑。
多个更改:
refactor(database): 优化查询性能
- 在频繁查询的列上添加索引
- 实现连接池
- 使用Redis缓存常见查询
- 更新ORM配置以提高性能
这些更改将平均查询时间从200ms减少到50ms。
见references/conventional-commits.md获取完整指南。
基本Git命令
日常命令
检查状态:
git status # 查看工作树状态
git diff # 显示未暂存更改
git diff --staged # 显示已暂存更改
进行提交:
git add <文件> # 暂存特定文件
git add . # 暂存所有更改
git commit -m "类型: 消息" # 提交带消息
git commit # 打开编辑器输入提交消息
与远程同步:
git pull origin main # 从主分支获取并合并
git push origin <分支> # 推送分支到远程
git fetch origin # 获取但不合并
分支管理:
git branch # 列出本地分支
git branch -a # 列出所有分支(包括远程)
git checkout -b <分支> # 创建并切换到分支
git checkout <分支> # 切换到现有分支
git branch -d <分支> # 删除本地分支
工作流命令
从主分支更新特性分支:
git checkout main
git pull origin main
git checkout feat/my-feature
git rebase main # 保持线性历史
# 如有冲突,解决
git push --force-with-lease origin feat/my-feature
修改最后一次提交:
git commit --amend # 编辑最后一次提交消息/内容
git commit --amend --no-edit # 添加更改到最后一次提交
取消暂存更改:
git reset HEAD <文件> # 取消暂存文件
git reset HEAD . # 取消暂存所有
丢弃更改:
git checkout -- <文件> # 丢弃文件中的更改
git restore <文件> # 现代替代
git clean -fd # 删除未跟踪文件/目录
暂存更改:
git stash # 暂存工作更改
git stash push -m "消息" # 带消息暂存
git stash list # 列出暂存
git stash apply # 应用最近暂存
git stash pop # 应用并移除暂存
git stash drop # 移除暂存
查看历史:
git log # 显示提交历史
git log --oneline # 紧凑历史
git log --graph # 可视化分支图
git log -p # 显示补丁
git log --follow <文件> # 跟踪文件历史
比较分支:
git diff main..feat/branch # 分支与主分支的更改
git log main..feat/branch # 分支中不在主分支的提交
见references/git-commands.md获取完整命令参考。
GitHub拉取请求工作流
创建PR
1. 推送分支:
git push -u origin feat/user-authentication
2. 在GitHub上创建PR:
标题: 使用Conventional Commit格式
feat(auth): 添加OAuth2认证
描述模板:
## 摘要
更改和动机的简要描述。
## 更改
- 列出关键更改
- 使用要点
- 具体化
## 测试
如何测试这些更改:
1. 分步说明
2. 预期行为
## 截图(如果是UI更改)
[添加截图]
## 检查清单
- [ ] 测试已添加/更新
- [ ] 文档已更新
- [ ] 无重大更改(或已记录)
- [ ] 遵循Conventional Commits
3. 请求审查者 4. 链接相关问题
审查PRs
作为审查者:
- 检查代码质量和风格
- 验证测试充分
- 本地测试功能
- 提问,建议改进
- 批准或请求更改
PR审查检查清单:
- [ ] 代码遵循项目约定
- [ ] 更改经过充分测试
- [ ] 无不必要的更改
- [ ] 文档已更新(如需)
- [ ] 提交消息遵循Conventional Commits
- [ ] 无安全漏洞引入
- [ ] 考虑性能影响
处理审查反馈
1. 进行请求的更改:
# 在您的分支中进行更改
git add .
git commit -m "fix(auth): 处理PR反馈"
git push origin feat/user-authentication
2. 回应评论 3. 标记对话为已解决 4. 请求重新审查
合并PRs
合并策略:
压缩合并(推荐用于大多数特性):
- 将所有提交合并为一个
- 清洁主分支历史
- 丢失详细提交历史
- 适合:有许多小提交的特性
合并提交(用于协作分支):
- 保留所有提交
- 显示分支历史
- 可能弄乱主历史
- 适合:有意义的提交历史的复杂特性
变基合并(用于清洁分支):
- 直接将提交应用到主分支
- 线性历史
- 需要清洁分支历史
- 适合:有精心制作提交的分支
合并后:
# 删除远程分支(或使用GitHub自动删除)
git push origin --delete feat/user-authentication
# 更新本地主分支
git checkout main
git pull origin main
# 删除本地分支
git branch -d feat/user-authentication
见references/github-workflow.md获取详细GitHub指导。
分支保护规则
在GitHub上为主分支配置:
必需:
- [x] 合并前需要拉取请求
- [x] 需要批准(至少1个)
- [x] 需要状态检查通过
- [x] 需要分支是最新的
推荐:
- [x] 需要对话解决
- [x] 需要线性历史
- [x] 不允许绕过设置
- [x] 自动删除头部分支
可选(针对团队):
- [ ] 需要代码所有者审查
- [ ] 限制推送访问
- [ ] 需要签名提交
处理合并冲突
冲突发生时
合并期间:
git merge main
# 在file.py中冲突
变基期间:
git rebase main
# 在file.py中冲突
解决过程
1. 查看冲突:
git status # 显示冲突文件
2. 打开冲突文件:
<<<<<<< HEAD
# 您的更改
=======
# 他们的更改
>>>>>>> main
3. 手动解决:
- 选择一个版本,或
- 结合两者,或
- 编写新解决方案
4. 标记为已解决:
git add file.py
5. 继续操作:
# 对于合并:
git commit
# 对于变基:
git rebase --continue
6. 如需要中止:
# 对于合并:
git merge --abort
# 对于变基:
git rebase --abort
防止冲突
- 频繁从主分支拉取/变基
- 保持分支短生命周期
- 与团队协调重叠工作
- 进行小而专注的更改
见references/troubleshooting.md获取复杂冲突场景。
常见工作流
开始新特性
# 1. 确保主分支是最新的
git checkout main
git pull origin main
# 2. 创建特性分支
git checkout -b feat/new-feature
# 3. 进行更改并提交
git add .
git commit -m "feat(module): 添加新功能"
# 4. 推送并创建PR
git push -u origin feat/new-feature
# 在GitHub上创建PR
快速错误修复
# 1. 从主分支创建修复分支
git checkout main
git pull origin main
git checkout -b fix/bug-description
# 2. 修复并提交
git add .
git commit -m "fix(module): 解决错误描述"
# 3. 推送并创建PR
git push -u origin fix/bug-description
# 使用“修复 #问题编号”创建PR
从主分支更新分支
# 选项1:变基(清洁历史首选)
git checkout feat/my-feature
git fetch origin
git rebase origin/main
# 如有冲突,解决
git push --force-with-lease origin feat/my-feature
# 选项2:合并(保留分支历史)
git checkout feat/my-feature
git fetch origin
git merge origin/main
git push origin feat/my-feature
分割大分支
# 如果分支太大,分割为更小PRs:
# 1. 创建第一个子特性
git checkout -b feat/user-auth-part1 feat/user-auth
git rebase -i main # 仅标记第一个提交为选择
git push -u origin feat/user-auth-part1
# 为第一部分创建PR
# 2. 第一部分合并后,继续第二部分
git checkout main
git pull origin main
git checkout -b feat/user-auth-part2 feat/user-auth
# 继续剩余提交
Git最佳实践
提交实践
✅ 做:
- 频繁提交(每天多次)
- 保持提交专注(一个逻辑更改)
- 写有意义的提交消息
- 遵循Conventional Commits格式
- 提交前测试
- 提交前审查更改(
git diff)
❌ 不做:
- 提交损坏代码到主分支
- 做包含无关更改的巨大提交
- 写模糊消息(“修复东西”、“更新”)
- 提交注释掉的代码
- 提交敏感数据(秘密、凭据)
- 强制推送到主分支
分支实践
✅ 做:
- 保持分支短生命周期(天而非周)
- 每个分支一个特性/修复
- 使用描述性分支名称
- 合并后立即删除分支
- 频繁从主分支变基/合并
- 保持主分支始终可部署
❌ 不做:
- 创建长期特性分支
- 在一个分支中混合多个特性
- 直接推送到主分支(无PR)
- 留下陈旧分支
- 让分支落后主分支太多
协作实践
✅ 做:
- 开始工作前拉取
- 沟通重叠工作
- 及时审查他人PRs
- 提供建设性反馈
- 回应审查评论
- 使用PR模板
- 在PRs中链接问题
❌ 不做:
- 直接在主分支上工作
- 强制推送到共享分支(无沟通)
- 未经审查批准PRs
- 忽略CI失败
- 未经审查合并自己的PRs
存储库卫生
✅ 做:
- 正确使用
.gitignore - 保持存储库清洁
- 在README中记录
- 标记发布
- 归档旧分支
- 使用GitHub发布
❌ 不做:
- 提交构建工件
- 提交依赖项(除非必要)
- 提交IDE特定文件
- 提交大型二进制文件
- 让主分支与生产分歧
常见故障排除问题
“我提交到了错误分支”
# 将提交移动到新分支
git branch feat/new-branch # 在当前提交创建分支
git reset --hard HEAD~1 # 从当前分支移除提交
git checkout feat/new-branch # 切换到新分支
“我需要撤销最后一次提交”
# 保留更改,撤销提交
git reset --soft HEAD~1
# 撤销提交和更改
git reset --hard HEAD~1
# 撤销但保持为未提交
git reset HEAD~1
“我提交了敏感数据”
# 从最后一次提交移除
git rm --cached <文件>
git commit --amend
git push --force-with-lease
# 从历史移除(使用如BFG Repo-Cleaner工具)
# 然后轮换任何暴露的秘密!
“我的分支与主分支分歧”
# 通过变基修复
git fetch origin
git rebase origin/main
# 解决冲突
git push --force-with-lease origin feat/my-branch
“我需要更改提交消息”
# 仅最后一次提交
git commit --amend
# 较旧提交
git rebase -i HEAD~3 # 对于最后3个提交
# 将'pick'改为'reword'以更改提交
“变基出错”
# 中止并重新开始
git rebase --abort
# 或如果已混乱
git reflog # 查找之前状态
git reset --hard <previous-commit>
见references/troubleshooting.md获取更多场景。
高级Git主题
交互式变基
# 交互式变基最后3个提交
git rebase -i HEAD~3
# 选项:
# pick - 保留提交
# reword - 更改提交消息
# edit - 暂停以修改提交
# squash - 与前一个提交合并
# fixup - 类似squash但丢弃消息
# drop - 移除提交
樱桃挑选
# 将特定提交应用到当前分支
git cherry-pick <提交哈希>
# 樱桃挑选多个提交
git cherry-pick <commit1> <commit2>
# 樱桃挑选范围
git cherry-pick <start>..<end>
引用日志(恢复丢失提交)
# 查看引用日志
git reflog
# 查找丢失提交
git reflog show HEAD
# 恢复到之前状态
git reset --hard HEAD@{2}
二分查找(查找引入错误的提交)
# 开始二分查找
git bisect start
git bisect bad # 当前提交是坏的
git bisect good <提交> # 最后已知好提交
# Git将检出中间提交,测试它
git bisect good # 如果工作
git bisect bad # 如果损坏
# 重复直到找到
git bisect reset # 返回到原始状态
工作树(处理多个分支)
# 为不同分支创建工作树
git worktree add ../project-feature feat/feature
# 列出工作树
git worktree list
# 移除工作树
git worktree remove ../project-feature
见references/advanced-git.md获取详细覆盖。
GitHub Actions集成
基本CI工作流
# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 设置
uses: actions/setup-node@v3
with:
node-version: '18'
- name: 安装
run: npm ci
- name: 测试
run: npm test
- name: 代码检查
run: npm run lint
Conventional Commit验证
# .github/workflows/commit-lint.yml
name: 提交代码检查
on: [pull_request]
jobs:
lint-commits:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v5
见examples/github-actions/获取更多工作流示例。
工具和资源
推荐工具
提交消息助手:
commitizen- 交互式提交消息构建器commitlint- 验证提交消息husky- 用于验证的Git钩子
GitHub CLI:
gh pr create --title "feat: 添加特性" --body "描述"
gh pr checkout 123
gh pr review --approve
gh pr merge --squash
可视化工具:
gitk- 内置Git GUI- GitKraken、SourceTree - 全功能GUIs
- VS Code Git集成
- GitHub Desktop
配置
有用git配置:
# 用户信息
git config --global user.name "您的名字"
git config --global user.email "your.email@example.com"
# 编辑器
git config --global core.editor "vim"
# 默认分支
git config --global init.defaultBranch main
# 默认变基
git config --global pull.rebase true
# 有用的别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.cm commit
git config --global alias.lg "log --oneline --graph --decorate"
学习资源
- references/conventional-commits.md - 完整Conventional Commits指南
- references/trunk-based-development.md - 详细TBD工作流
- references/github-workflow.md - GitHub特定实践
- references/git-commands.md - 全面命令参考
- references/troubleshooting.md - 问题解决指南
- references/advanced-git.md - 高级技术
- examples/ - 示例提交消息、PR模板、工作流
- assets/templates/ - PRs、提交、检查清单的模板
何时使用此技能
激活用于涉及以下请求:
- Git命令和操作
- 分支和合并策略
- 提交消息格式化
- 拉取请求创建和审查
- 合并冲突解决
- 存储库管理
- GitHub工作流问题
- Git故障排除
- 版本控制最佳实践
- 使用Git的团队协作
快速参考
日常命令:
git status # 检查状态
git add . # 暂存更改
git commit -m "类型: 消息" # 提交
git pull origin main # 从主分支更新
git push origin branch # 推送更改
分支工作流:
git checkout main # 切换到主分支
git pull origin main # 更新
git checkout -b feat/name # 创建分支
# ... 进行更改 ...
git push -u origin feat/name # 推送并创建PR
Conventional Commit:
类型(范围): 主题
- 使用feat、fix、docs、style、refactor、test、chore
- 主题使用祈使语气
- 正文可选用于详细信息
- 页脚可选用于重大更改/问题
保持更新:
git fetch origin # 获取更新
git rebase origin/main # 在主分支上变基
git push --force-with-lease # 安全强制推送
记住: 小提交、频繁集成、清晰消息、短生命周期分支,以及始终保持主分支可部署。这是专业版本控制的道路。