name: git-workflow description: 使用Git有效管理源代码控制,包括分支策略、提交约定、合并冲突解决、变基以及协作工作流程,如GitHub Flow或GitFlow。适用于管理功能分支、创建有意义的提交、解决合并冲突、变基分支、压缩提交、使用交互式变基、实施分支命名约定、遵循提交消息标准、管理拉取请求或在团队环境中协作。
Git工作流程 - 专业版本控制
何时使用此技能
- 管理功能分支和分支策略
- 创建清晰、有意义的提交消息
- 有效解决合并冲突
- 变基分支以保持干净历史
- 合并前压缩提交
- 使用交互式变基清理历史
- 实施分支命名约定
- 遵循提交消息标准(Conventional Commits)
- 管理拉取请求和代码审查
- 在团队Git工作流程中协作
- 从Git错误中恢复(重置、还原、引用日志)
- 管理发布分支和热修复
何时使用此技能
- 管理代码变更、与团队协作、创建分支、处理冲突和保持干净的git历史。
- 当处理相关任务或功能时
- 在需要此专业知识的开发过程中
使用时机:管理代码变更、与团队协作、创建分支、处理冲突和保持干净的git历史。
核心原则
- 频繁提交,稳定时推送 - 小而专注的提交易于审查和还原
- 主分支神圣不可侵犯 - 始终可部署,从不直接提交
- 清晰历史讲述故事 - 未来开发者通过提交消息理解原因
- 分享前审查 - 提交前检查
git diff
基本命令
开始工作
# 更新本地仓库
git fetch origin
git pull origin main
# 创建功能分支
git checkout -b feature/user-authentication
# 或: git switch -c feature/user-authentication
# 分支命名约定:
# feature/描述 - 新功能
# fix/描述 - 错误修复
# refactor/描述 - 代码改进
# docs/描述 - 文档
进行变更
# 检查变更
git status # 概览
git diff # 未暂存变更
git diff --staged # 已暂存变更
git diff main...HEAD # 分支后的所有变更
# 暂存变更
git add path/to/file # 特定文件
git add path/to/directory # 整个目录
git add -p # 交互式暂存(推荐!)
# 提交好消息
git commit -m "feat: 添加用户认证端点
- 实现JWT令牌生成
- 添加bcrypt密码哈希
- 创建认证验证中间件
关闭 #123"
提交消息格式
使用Conventional Commits:
<类型>(<范围>): <主题>
<正文>
<页脚>
类型:
feat:新功能fix:错误修复refactor:代码变更,既不修复错误也不添加功能docs:仅文档style:格式化、缺少分号等test:添加测试chore:维护任务perf:性能改进
示例:
# 好的提交
git commit -m "feat: 添加用户头像上传"
git commit -m "fix: 防止订单处理中的竞态条件"
git commit -m "refactor: 将验证逻辑提取到单独模块"
# 坏的提交(太模糊)
git commit -m "修复东西" # 什么东西?
git commit -m "WIP" # 永远不要推送WIP提交
git commit -m "asdf" # 无意义
查看历史
# 最近提交
git log --oneline -10
# 带差异的提交
git log -p -2
# 可视化分支图
git log --graph --oneline --all
# 查找谁更改了一行
git blame path/to/file
# 搜索提交消息
git log --grep="authentication"
# 按作者查找提交
git log --author="alice"
分支与合并
# 列出分支
git branch # 本地
git branch -r # 远程
git branch -a # 所有
# 切换分支
git checkout main
# 或: git switch main
# 合并功能分支
git checkout main
git merge feature/user-auth # 创建合并提交
git merge --squash feature/user-auth # 压缩成一个提交
# 合并后删除分支
git branch -d feature/user-auth # 安全删除(仅合并后)
git branch -D feature/user-auth # 强制删除
git push origin --delete feature/user-auth # 删除远程
处理冲突
# 当发生合并冲突时:
# 1. 查看冲突文件
git status
# 2. 打开文件,手动解决冲突
# 查找: <<<<<<< HEAD, =======, >>>>>>> branch
# 3. 标记为已解决
git add path/to/resolved-file
# 4. 完成合并
git commit # 使用默认合并消息
# 或中止合并
git merge --abort
冲突示例:
<<<<<<< HEAD
const apiUrl = 'https://api.prod.example.com';
=======
const apiUrl = 'https://api-v2.example.com';
>>>>>>> feature/update-api
// 解决后(选择合适版本):
const apiUrl = 'https://api-v2.example.com';
撤销变更
# 撤销工作目录变更(未暂存)
git checkout -- path/to/file
# 或: git restore path/to/file
# 取消暂存文件(保留变更)
git reset HEAD path/to/file
# 或: git restore --staged path/to/file
# 撤销最后一次提交(保留变更)
git reset --soft HEAD~1
# 撤销最后一次提交(丢弃变更) ⚠️ 危险
git reset --hard HEAD~1
# 还原一个提交(创建新提交)
git revert abc123
# 修改最后一次提交(推送前)
git commit --amend
git commit --amend --no-edit # 保留消息
存储
# 保存进行中的工作
git stash
# 带消息存储
git stash save "WIP: 处理用户个人资料"
# 列出存储
git stash list
# 应用最近存储
git stash apply
# 应用并从存储列表中移除
git stash pop
# 应用特定存储
git stash apply stash@{2}
# 删除存储
git stash drop stash@{0}
# 清除所有存储
git stash clear
变基
# 用主分支变更更新分支
git checkout feature/user-auth
git rebase main
# 交互式变基(清理历史)
git rebase -i HEAD~5
# 变基期间:
# - pick: 保留提交
# - reword: 更改提交消息
# - squash: 与前一提交合并
# - fixup: 类似squash但丢弃消息
# - drop: 移除提交
# 如果出错,中止变基
git rebase --abort
# 解决冲突后继续
git rebase --continue
⚠️ 永远不要在共享分支上变基已推送的提交!
樱桃挑选
# 将特定提交应用到当前分支
git cherry-pick abc123
# 樱桃挑选多个提交
git cherry-pick abc123 def456
# 樱桃挑选而不提交(仅暂存)
git cherry-pick -n abc123
工作流程模式
功能分支工作流程
# 1. 从主分支创建分支
git checkout main
git pull origin main
git checkout -b feature/new-feature
# 2. 进行变更并提交
# ... 工作工作 ...
git add .
git commit -m "feat: 实现新功能"
# 3. 保持分支与主分支更新
git fetch origin
git rebase origin/main
# 4. 推送到远程
git push origin feature/new-feature
# 5. 在GitHub/GitLab上创建拉取请求
# 6. PR批准和合并后,清理
git checkout main
git pull origin main
git branch -d feature/new-feature
Gitflow工作流程
# 主分支:
# - main (生产)
# - develop (集成)
# 支持分支:
# - feature/* (新功能)
# - release/* (发布准备)
# - hotfix/* (紧急修复)
# 开始功能
git checkout develop
git checkout -b feature/awesome-feature
# 完成功能
git checkout develop
git merge --no-ff feature/awesome-feature
git branch -d feature/awesome-feature
# 创建发布
git checkout develop
git checkout -b release/1.2.0
# ... 升级版本,更新变更日志 ...
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "发布 1.2.0"
# 热修复
git checkout main
git checkout -b hotfix/critical-bug
# ... 修复错误 ...
git checkout main
git merge --no-ff hotfix/critical-bug
git checkout develop
git merge --no-ff hotfix/critical-bug
git tag -a v1.2.1 -m "热修复 1.2.1"
主干式开发
# 每个人都频繁提交到主分支
# 短寿命功能分支(<1天)
# 未完成工作使用功能标志
git checkout main
git pull origin main
git checkout -b feature/quick-change
# ... 进行小变更 ...
git commit -am "feat: 添加按钮"
git push origin feature/quick-change
# 创建PR,快速审查,合并
# 合并后立即删除分支
Git配置
基本配置
# 用户身份
git config --global user.name "您的姓名"
git config --global user.email "you@example.com"
# 编辑器
git config --global core.editor "code --wait" # VS Code
# 或: vim, nano, emacs, 等
# 默认分支名称
git config --global init.defaultBranch main
# 有用的别名
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual 'log --graph --oneline --all'
# 自动纠正拼写错误
git config --global help.autocorrect 20
# 彩色输出
git config --global color.ui auto
# 仅推送当前分支
git config --global push.default current
# 默认使用变基拉取
git config --global pull.rebase true
.gitignore
# 创建全局gitignore
git config --global core.excludesfile ~/.gitignore_global
# 常见条目:
# 操作系统文件
.DS_Store
Thumbs.db
# 编辑器文件
.vscode/
.idea/
*.swp
*.swo
*~
# 依赖
node_modules/
venv/
vendor/
# 构建输出
dist/
build/
*.pyc
*.class
# 秘密
.env
.env.local
secrets.yml
*.pem
# 日志
*.log
logs/
高级技巧
Git工作树
# 同时处理多个分支
git worktree add ../project-feature2 feature/feature2
cd ../project-feature2 # 独立目录,相同仓库
# 列出工作树
git worktree list
# 移除工作树
git worktree remove ../project-feature2
二分查找(找到破坏提交)
# 二分查找坏提交
git bisect start
git bisect bad # 当前状态已坏
git bisect good v1.0.0 # 最后已知好版本
# Git检出提交进行测试
# 手动测试或: git bisect run ./test.sh
git bisect good # 如果测试通过
git bisect bad # 如果测试失败
# 重复直到找到
# git bisect reset返回原始状态
引用日志(安全网)
# 查看所有最近操作(即使在重置后)
git reflog
# 恢复“丢失”提交
git checkout abc123 # 从引用日志
# 撤销错误重置
git reset --hard HEAD@{2}
最佳实践
✅ 做
- 写清晰、描述性提交消息
- 提交逻辑变更单元
- 提交前审查差异(
git diff --staged) - 推送前拉取
- 保持提交小而专注
- 对所有变更使用分支
- 合并后删除分支
❌ 不做
- 提交秘密或凭据
- 提交生成文件(构建产物)
- 直接提交到主分支
- 在共享分支上重写历史
- 创建包含无关变更的大提交
- 使用模糊提交消息
- 推送破坏的代码
故障排除
常见问题
“分离的HEAD”:
# 您直接检出了一个提交
# 保存工作:
git checkout -b new-branch-name
“大文件中的合并冲突”:
# 使用他们的或我们的:
git checkout --theirs path/to/file # 采用他们的版本
git checkout --ours path/to/file # 保留我们的版本
git add path/to/file
“意外提交到主分支”:
# 移动提交到新分支
git branch feature/accidental
git reset --hard origin/main
git checkout feature/accidental
“推送了敏感数据”:
# 使用BFG Repo Cleaner或git-filter-repo
# 警告: 重写历史,与团队协调
# 然后强制推送(⚠️ 危险)
git push --force-with-lease
资源
记住:Git是您代码的时间机器。用它创建检查点,安全地探索替代解决方案,并维护变更原因的清晰历史。