Chenyj Space
返回博客
·33 分钟

Git 工作流最佳实践:从入门到精通

Git版本控制工作流协作工具

Git 基础回顾

核心概念

bash
# 工作区 → 暂存区 → 本地仓库 → 远程仓库
git add .          # 工作区 → 暂存区
git commit         # 暂存区 → 本地仓库
git push           # 本地仓库 → 远程仓库

# 反向操作
git checkout .     # 暂存区 → 工作区
git reset HEAD     # 本地仓库 → 暂存区
git revert         # 创建新的撤销提交

常用命令

bash
# 查看状态
git status
git log --oneline --graph
git diff

# 分支操作
git branch feature
git checkout feature
git checkout -b feature  # 创建并切换
git branch -d feature    # 删除分支

# 合并操作
git merge feature
git rebase main

# 远程操作
git fetch origin
git pull origin main
git push origin feature

分支策略

Git Flow

适用场景:大型项目、正式发布

code
main (生产)
  |
  ├── develop (开发)
  |     |
  |     ├── feature/user-auth
  |     ├── feature/payment
  |     └── feature/dashboard
  |
  ├── release/1.0.0 (发布)
  |
  └── hotfix/fix-login (热修复)

分支说明

分支用途生命周期
main生产代码永久
develop开发代码永久
feature/*功能开发临时
release/*版本发布临时
hotfix/*紧急修复临时

工作流程

bash
# 1. 创建功能分支
git checkout develop
git checkout -b feature/user-auth

# 2. 开发功能
git add .
git commit -m "feat: add user authentication"

# 3. 合并到 develop
git checkout develop
git merge feature/user-auth

# 4. 发布版本
git checkout -b release/1.0.0
# 测试、修复...
git checkout main
git merge release/1.0.0
git tag v1.0.0

# 5. 紧急修复
git checkout main
git checkout -b hotfix/fix-login
# 修复...
git checkout main
git merge hotfix/fix-login
git checkout develop
git merge hotfix/fix-login

GitHub Flow

适用场景:小型项目、持续部署

code
main (生产)
  |
  └── feature-branch (功能分支)

工作流程

bash
# 1. 创建功能分支
git checkout main
git checkout -b feature/user-auth

# 2. 开发和提交
git add .
git commit -m "feat: add user authentication"

# 3. 推送并创建 PR
git push origin feature/user-auth
# 在 GitHub 上创建 Pull Request

# 4. 代码审查和合并
# 审查通过后,通过 GitHub 合并到 main

# 5. 部署
# main 分支自动部署

GitLab Flow

适用场景:多环境部署

code
main (生产)
  |
  ├── pre-production (预生产)
  |
  └── development (开发)

工作流程

bash
# 1. 功能开发
git checkout development
git checkout -b feature/user-auth
# 开发完成后合并到 development

# 2. 预生产测试
git checkout pre-production
git merge development

# 3. 生产部署
git checkout main
git merge pre-production

提交规范

Conventional Commits

格式

code
<type>(<scope>): <description>

[optional body]

[optional footer]

类型

类型说明示例
feat新功能feat(auth): add login
fix修复 bugfix(api): handle null response
docs文档更新docs(readme): update install guide
style代码格式style: fix indentation
refactor重构refactor(auth): simplify validation
test测试test(auth): add unit tests
chore构建/工具chore(deps): update dependencies

示例

bash
# 简单提交
git commit -m "feat(auth): add user login"

# 带详细说明
git commit -m "$(cat <<'EOF'
feat(auth): add user login

- Add login form component
- Implement authentication API
- Add JWT token handling

Closes #123
EOF
)"

# 破坏性变更
git commit -m "$(cat <<'EOF'
feat(api)!: change response format

BREAKING CHANGE: API response now returns data in 'result' field
EOF
)"

提交信息工具

commitizen

bash
# 安装
npm install -g commitizen cz-conventional-changelog

# 使用
git cz

commitlint

bash
# 安装
npm install --save-dev @commitlint/cli @commitlint/config-conventional

# 配置 commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
};

# Git hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'

代码审查

Pull Request 最佳实践

标题和描述

markdown
## 功能描述
简要说明这个 PR 做了什么

## 改动内容
- 添加了用户认证模块
- 实现了 JWT token 验证
- 更新了 API 文档

## 测试
- [x] 单元测试通过
- [x] 集成测试通过
- [x] 手动测试通过

## 相关 Issue
Closes #123

代码审查清单

markdown
## 代码质量
- [ ] 代码符合项目规范
- [ ] 没有明显的代码重复
- [ ] 命名清晰易懂
- [ ] 注释适当

## 功能实现
- [ ] 功能符合需求
- [ ] 边界情况处理
- [ ] 错误处理完善
- [ ] 性能考虑

## 安全性
- [ ] 输入验证
- [ ] 权限检查
- [ ] 敏感数据处理
- [ ] SQL 注入/XSS 防护

## 测试
- [ ] 单元测试覆盖
- [ ] 集成测试
- [ ] 边界测试
- [ ] 错误场景测试

审查技巧

建设性反馈

markdown
# ❌ 不好
"这个代码有问题"

# ✅ 好
"这里可能会有空指针异常,建议添加 null check:
```javascript
if (user && user.name) {
  // ...
}
```"

# ✅ 好
"这个函数可以简化为:
```javascript
const result = data.map(item => item.value);

这样更简洁易读。"

code

**提问而非命令**:

```markdown
# ❌ 不好
"把这里的 const 改成 let"

# ✅ 好
"这里使用 const 是因为值不会被重新赋值吗?如果是的话,当前实现是正确的。"

# ✅ 好
"考虑使用 Map 代替对象,因为这里需要频繁的增删操作,Map 性能更好。你觉得呢?"

冲突解决

冲突类型

内容冲突

bash
<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = 10000;
>>>>>>> feature/new-timeout

删除冲突

bash
<<<<<<< HEAD
// 文件被删除
=======
// 文件被修改
function newFunction() { ... }
>>>>>>> feature/new-function

解决策略

手动解决

bash
# 1. 查看冲突
git status

# 2. 编辑冲突文件
# 手动选择保留哪些代码

# 3. 标记为已解决
git add <conflicted-file>

# 4. 继续合并
git merge --continue
# 或
git rebase --continue

使用工具

bash
# 使用 VS Code
code --merge <conflicted-file>

# 使用 Git mergetool
git mergetool

# 配置 mergetool
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'

预防冲突

频繁同步

bash
# 经常从主分支拉取更新
git checkout feature/my-feature
git fetch origin
git rebase origin/main

# 或使用 merge
git merge origin/main

小步提交

bash
# ❌ 不好:大量改动
git add .
git commit -m "feat: add entire feature"

# ✅ 好:小步提交
git add src/auth/login.ts
git commit -m "feat(auth): add login form"

git add src/auth/api.ts
git commit -m "feat(auth): add authentication API"

git add src/auth/jwt.ts
git commit -m "feat(auth): add JWT handling"

高级技巧

Interactive Rebase

bash
# 交互式 rebase(整理提交历史)
git rebase -i HEAD~3

# 编辑器会显示:
pick abc1234 feat: add login form
pick def5678 fix: typo in login
pick ghi9012 feat: add validation

# 修改为:
pick abc1234 feat: add login form
squash def5678 fix: typo in login  # 合并到上一个提交
pick ghi9012 feat: add validation

Cherry-pick

bash
# 从其他分支选择特定提交
git cherry-pick abc1234

# 选择多个提交
git cherry-pick abc1234 def5678

# 选择提交范围
git cherry-pick abc1234..ghi9012

Stash

bash
# 暂存当前工作
git stash

# 查看暂存列表
git stash list

# 恢复暂存
git stash pop  # 恢复并删除
git stash apply  # 恢复但不删除

# 暂存特定文件
git stash push -m "work in progress" src/feature.ts

# 恢复特定暂存
git stash pop stash@{1}

Reflog

bash
# 查看操作历史
git reflog

# 恢复误删的分支
git checkout -b recovered-branch HEAD@{2}

# 恢复误操作的提交
git reset --hard HEAD@{1}

工作流最佳实践

1. 分支命名规范

bash
# 功能分支
feature/user-auth
feature/payment-integration
feature/dashboard-v2

# 修复分支
fix/login-crash
fix/memory-leak

# 热修复
hotfix/security-patch
hotfix/critical-bug

# 发布分支
release/v1.0.0
release/v2.0.0-beta

2. 提交频率

bash
# ❌ 不好:一天一次大提交
git add .
git commit -m "feat: implement entire feature"

# ✅ 好:频繁小提交
git add src/login.ts
git commit -m "feat(auth): add login form"

git add src/validation.ts
git commit -m "feat(auth): add input validation"

git add src/api.ts
git commit -m "feat(auth): add API integration"

git add tests/
git commit -m "test(auth): add unit tests"

3. 代码审查流程

bash
# 1. 创建功能分支
git checkout -b feature/user-auth

# 2. 开发和提交
# ... 多次提交 ...

# 3. 整理提交历史
git rebase -i main

# 4. 推送并创建 PR
git push origin feature/user-auth

# 5. 代码审查
# - 同事审查代码
# - 自动化测试运行
# - CI/CD 检查

# 6. 修改和更新
# 根据审查意见修改
git add .
git commit -m "fix: address review comments"
git push origin feature/user-auth

# 7. 合并
# 审查通过后,通过 GitHub 合并

4. 发布流程

bash
# 1. 创建发布分支
git checkout develop
git checkout -b release/v1.0.0

# 2. 最后的修复和测试
git commit -m "fix: last minute fixes"

# 3. 合并到 main
git checkout main
git merge release/v1.0.0
git tag -a v1.0.0 -m "Release v1.0.0"

# 4. 合并回 develop
git checkout develop
git merge release/v1.0.0

# 5. 推送
git push origin main --tags
git push origin develop

# 6. 清理
git branch -d release/v1.0.0
git push origin --delete release/v1.0.0

Git 配置

全局配置

bash
# 用户信息
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# 编辑器
git config --global core.editor "code --wait"

# 差异工具
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'

# 合并工具
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'

# 别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.lg "log --oneline --graph --decorate"

.gitconfig 文件

ini
[user]
    name = Your Name
    email = your.email@example.com

[core]
    editor = code --wait
    autocrlf = input  # Windows: true, Linux/Mac: input

[alias]
    st = status
    co = checkout
    br = branch
    ci = commit
    lg = log --oneline --graph --decorate
    last = log -1 HEAD
    unstage = reset HEAD --

[pull]
    rebase = true

[push]
    default = current

[merge]
    tool = vscode
    conflictstyle = diff3

[diff]
    tool = vscode

常见问题解决

1. 误删分支

bash
# 查看 reflog
git reflog

# 恢复分支
git checkout -b recovered-branch HEAD@{2}

2. 误操作提交

bash
# 撤销最后一次提交(保留更改)
git reset --soft HEAD~1

# 撤销最后一次提交(丢弃更改)
git reset --hard HEAD~1

# 恢复已删除的提交
git reflog
git reset --hard HEAD@{1}

3. 大文件处理

bash
# 使用 Git LFS
git lfs install
git lfs track "*.psd"
git lfs track "*.zip"

# .gitattributes
*.psd filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text

4. 子模块

bash
# 添加子模块
git submodule add https://github.com/user/repo.git path/to/repo

# 克隆包含子模块的仓库
git clone --recurse-submodules https://github.com/user/project.git

# 更新子模块
git submodule update --remote

总结

核心原则

  1. 频繁提交:小步快跑,易于回滚
  2. 清晰的提交信息:说明做了什么和为什么
  3. 代码审查:保证代码质量
  4. 分支策略:适合团队的工作流
  5. 冲突预防:频繁同步,小步提交

工具推荐

  1. Git GUI:GitKraken、SourceTree、VS Code
  2. 代码审查:GitHub、GitLab、Bitbucket
  3. CI/CD:GitHub Actions、GitLab CI、Jenkins
  4. Git LFS:大文件管理

学习资源


延伸阅读