Skip to content

Git 代码评审

概述

代码评审(Code Review)是软件开发过程中保证代码质量的重要环节。通过代码评审,可以发现潜在问题、分享知识、提高团队整体代码水平。本指南将介绍代码评审的流程、清单、工具和技巧。

评审流程

标准流程

1. 提交代码 → 2. 创建 PR → 3. 自动检查 → 4. 人工评审 → 5. 修改完善 → 6. 合并代码

详细步骤

1. 提交者准备

bash
# 确保代码是最新的
git checkout main
git pull origin main

# 创建特性分支
git checkout -b feature/123-user-auth

# 开发和提交
git add .
git commit -m "feat: 添加用户认证功能"

# 推送到远程
git push origin feature/123-user-auth

2. 创建 Pull Request

markdown
## PR 标题
feat: 添加用户认证功能

## 变更描述
实现基于 JWT 的用户认证系统

## 变更内容
- 用户注册和登录
- Token 生成和验证
- 密码加密存储

## 测试计划
- [ ] 单元测试通过
- [ ] 集成测试通过
- [ ] 手动测试完成

## 相关 Issue
Closes #123

## 截图
(如有 UI 变更,添加截图)

3. 自动检查

yaml
# .github/workflows/pr-check.yml
name: PR Check

on:
  pull_request:
    branches: [main]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Lint
        run: npm run lint
      
      - name: Test
        run: npm test
      
      - name: Build
        run: npm run build
      
      - name: Coverage
        run: npm run coverage

4. 人工评审

markdown
## 评审者职责

1. 检查代码质量
2. 验证功能实现
3. 评估性能影响
4. 检查安全性
5. 确认测试覆盖

## 评审时间
- 小型 PR: 1 小时内
- 中型 PR: 4 小时内
- 大型 PR: 1 天内

5. 修改完善

bash
# 根据评审意见修改代码
git add .
git commit -m "refactor: 根据评审意见优化代码"

# 推送更新
git push origin feature/123-user-auth

6. 合并代码

bash
# 评审通过后合并
# 使用 squash 合并保持历史清晰
gh pr merge --squash

# 或使用 rebase 合并
gh pr merge --rebase

# 删除分支
git branch -d feature/123-user-auth
git push origin --delete feature/123-user-auth

评审清单

功能性检查

markdown
## 功能实现
- [ ] 代码实现了预期功能
- [ ] 边界情况已处理
- [ ] 错误处理完善
- [ ] 日志记录合理

## 业务逻辑
- [ ] 业务逻辑正确
- [ ] 符合需求规格
- [ ] 无逻辑漏洞
- [ ] 数据处理正确

代码质量检查

markdown
## 代码风格
- [ ] 遵循编码规范
- [ ] 命名规范合理
- [ ] 代码格式统一
- [ ] 注释清晰有用

## 代码结构
- [ ] 模块划分合理
- [ ] 函数职责单一
- [ ] 无重复代码
- [ ] 依赖关系清晰

## 可读性
- [ ] 代码易于理解
- [ ] 变量命名清晰
- [ ] 逻辑流程清晰
- [ ] 复杂逻辑有注释

测试检查

markdown
## 测试覆盖
- [ ] 单元测试已添加
- [ ] 测试用例合理
- [ ] 边界条件测试
- [ ] 异常情况测试

## 测试质量
- [ ] 测试通过
- [ ] 测试覆盖率高
- [ ] 测试代码质量好
- [ ] 测试独立可重复

性能检查

markdown
## 性能影响
- [ ] 无明显性能问题
- [ ] 数据库查询优化
- [ ] 无内存泄漏
- [ ] 资源使用合理

## 算法优化
- [ ] 算法复杂度合理
- [ ] 无不必要的循环
- [ ] 缓存使用得当
- [ ] 并发处理正确

安全检查

markdown
## 安全性
- [ ] 无安全漏洞
- [ ] 输入验证完善
- [ ] 输出编码正确
- [ ] 敏感数据保护

## 权限控制
- [ ] 权限检查正确
- [ ] 认证逻辑安全
- [ ] 敏感操作有保护
- [ ] 无越权访问

文档检查

markdown
## 文档更新
- [ ] README 已更新
- [ ] API 文档已更新
- [ ] 注释已添加
- [ ] 变更日志已更新

评审工具

GitHub 代码评审

内联评论

markdown
# 在代码行添加评论
建议使用更明确的变量名

```javascript
// 不好的命名
const x = getUser();

// 好的命名
const currentUser = getUser();

#### 评审建议

```markdown
# 使用建议功能
建议修改:

```suggestion
const currentUser = getUser();

#### 评审状态

```bash
# 批准 PR
gh pr review <pr-number> --approve --body "代码看起来不错!"

# 请求修改
gh pr review <pr-number> --request-changes --body "请修复以下问题"

# 添加评论
gh pr review <pr-number> --comment --body "有几点建议"

GitLab 代码评审

讨论线程

markdown
# 创建讨论
## 代码建议
建议将这个函数拆分为更小的函数,提高可读性。

## 评审状态
- 需要讨论
- 需要修改
- 已解决

批准规则

yaml
# .gitlab/merge_request_templates/Default.md
## 评审检查清单

### 必须项
- [ ] 代码遵循规范
- [ ] 测试通过
- [ ] 无安全问题

### 建议项
- [ ] 性能优化
- [ ] 文档完善

VS Code 扩展

GitLens

json
// settings.json
{
  "gitlens.codeLens.enabled": true,
  "gitlens.currentLine.enabled": true,
  "gitlens.hovers.enabled": true,
  "gitlens.blame.format": "${author} • ${date}"
}

GitHub Pull Requests

json
// settings.json
{
  "githubPullRequests.queries": [
    {
      "label": "Waiting For My Review",
      "query": "is:open review-requested:${user}"
    },
    {
      "label": "Assigned To Me",
      "query": "is:open assignee:${user}"
    }
  ]
}

自动化工具

Danger

ruby
# Dangerfile

# 检查 PR 描述
fail "请添加 PR 描述" if github.pr_body.length < 10

# 检查变更文件数量
warn "PR 变更文件过多 (#{git.lines_of_code}),考虑拆分" if git.lines_of_code > 500

# 检查测试文件
has_app_changes = !git.modified_files.grep(/src/).empty?
has_test_changes = !git.modified_files.grep(/test/).empty?

if has_app_changes && !has_test_changes
  warn "代码有变更,但没有添加测试", sticky: false
end

# 检查大文件
git.modified_files.each do |file|
  next unless File.extname(file) == ".lock"
  warn "Lock 文件有变更: #{file}"
end

# 检查 TODO
git.diff.scan(/TODO/).each do |match|
  warn "发现 TODO 注释"
end

CodeClimate

yaml
# .codeclimate.yml
version: "2"

plugins:
  eslint:
    enabled: true
    channel: "eslint-8"
  
  stylelint:
    enabled: true
  
  duplication:
    enabled: true
    config:
      languages:
        javascript:
          mass_threshold: 50
  
  fixme:
    enabled: true

exclude_patterns:
  - "node_modules/"
  - "dist/"
  - "*.min.js"

评审技巧

提交者技巧

1. 小步提交

bash
# 好的实践: 小 PR
git commit -m "feat: 添加用户模型"
git commit -m "feat: 添加用户控制器"
git commit -m "feat: 添加用户路由"

# 不好的实践: 大 PR
git commit -m "feat: 添加完整的用户管理系统"

2. 清晰描述

markdown
## PR 描述模板

### 变更内容
清晰描述本次变更的内容

### 变更原因
说明为什么要做这个变更

### 测试方法
说明如何测试这个变更

### 影响范围
说明这个变更的影响范围

### 注意事项
说明需要注意的事项

3. 自我评审

bash
# 推送前自我检查
git diff main...HEAD

# 检查提交信息
git log main..HEAD --oneline

# 运行测试
npm test

# 运行 lint
npm run lint

评审者技巧

1. 及时响应

markdown
## 响应时间建议

- 小型 PR (< 100 行): 1 小时内
- 中型 PR (100-500 行): 4 小时内
- 大型 PR (> 500 行): 1 天内

## 优先级

1. 紧急修复
2. 阻塞其他工作的 PR
3. 普通功能 PR
4. 优化和重构 PR

2. 建设性反馈

markdown
# 好的反馈方式

## 具体明确
"第 45 行的变量名 `x` 不够清晰,建议改为 `userId`"

## 解释原因
"建议使用 `const` 而不是 `let`,因为这个变量不会被重新赋值"

## 提供示例
```suggestion
const userId = getUserId();

鼓励和肯定

"这个实现思路很好!建议再优化一下命名"

不好的反馈方式

模糊不清

"这里有问题"

过于严厉

"这代码写得太烂了"

没有建设性

"我不喜欢这个实现"


#### 3. 关注重点

```markdown
## 优先关注

1. 功能正确性
2. 安全问题
3. 性能问题
4. 代码可读性
5. 代码风格

## 次要关注

1. 命名细节
2. 注释措辞
3. 代码格式

评审文化

建立良好文化

markdown
## 评审原则

1. **尊重他人**: 对事不对人
2. **开放心态**: 接受不同意见
3. **持续学习**: 从评审中学习
4. **积极反馈**: 及时给予反馈
5. **共同进步**: 帮助团队成长

## 评审礼仪

- 及时响应评审请求
- 给予建设性的反馈
- 解释评审意见的原因
- 感谢评审者的时间
- 保持专业和友善

避免的问题

markdown
## 常见问题

1. **评审拖延**: 长时间不响应
2. **评审敷衍**: 不仔细看代码
3. **评审苛刻**: 过于挑剔
4. **评审模糊**: 意见不明确
5. **评审冲突**: 意见不一致时处理不当

## 解决方案

1. 设置评审时间限制
2. 使用评审清单
3. 关注重点问题
4. 提供具体建议
5. 团队讨论达成共识

总结

有效的代码评审带来的好处:

代码质量:

  • 发现潜在问题
  • 提高代码质量
  • 保证代码一致性

团队协作:

  • 知识分享
  • 技能提升
  • 团队凝聚力

项目管理:

  • 降低维护成本
  • 减少 Bug 数量
  • 提高开发效率

通过建立良好的评审流程和文化,可以显著提高项目的整体质量和团队的技术水平。