# Git 提交规范

本文档定义了项目的 Git 提交信息格式规范，以保持提交历史的清晰和一致性。

## 提交格式

```
<类型>：<简短描述>

[可选的详细描述]

[可选的注释或关联 Issue]
```

## 提交类型

### 主要类型

| 类型 | 说明 | 示例 |
|------|------|------|
| `init` | 项目初始化 | `init：项目初始化，搭建Godot文件结构` |
| `feat` | 新增功能 | `feat：添加角色移动系统` |
| `fix` | 修复 Bug | `fix：修复角色跳跃时的碰撞检测问题` |
| `docs` | 文档更新 | `docs：更新 README 中的安装说明` |
| `style` | 代码格式调整（不影响功能） | `style：统一代码缩进格式` |
| `refactor` | 代码重构（不新增功能也不修复 Bug） | `refactor：重构敌人 AI 逻辑` |
| `perf` | 性能优化 | `perf：优化场景加载速度` |
| `test` | 添加或修改测试 | `test：添加角色控制器单元测试` |
| `chore` | 构建过程或辅助工具的变动 | `chore：更新 .gitignore 文件` |
| `revert` | 回滚之前的提交 | `revert：回滚 feat：添加角色移动系统` |

### 场景和资源相关

| 类型 | 说明 | 示例 |
|------|------|------|
| `scene` | 场景文件相关 | `scene：创建主菜单场景` |
| `asset` | 资源文件相关 | `asset：添加角色精灵图和动画` |
| `ui` | UI 界面相关 | `ui：设计游戏暂停菜单` |
| `audio` | 音频相关 | `audio：添加背景音乐和音效` |

### 游戏开发特定类型

| 类型 | 说明 | 示例 |
|------|------|------|
| `gameplay` | 游戏玩法相关 | `gameplay：实现敌人生成机制` |
| `level` | 关卡设计相关 | `level：完成第一关卡设计` |
| `config` | 配置文件相关 | `config：调整游戏难度参数` |
| `plugin` | 插件相关 | `plugin：集成对话系统插件` |

## 提交示例

### 基础示例

```bash
# 项目初始化
git commit -m "init：项目初始化，搭建Godot文件结构"

# 新增功能
git commit -m "feat：实现玩家角色的移动和跳跃"

# 修复问题
git commit -m "fix：修复敌人穿墙的碰撞问题"

# 文档更新
git commit -m "docs：添加 Git 提交规范文档"
```

### 带详细描述的示例

```bash
git commit -m "feat：添加存档系统

- 实现游戏进度保存功能
- 支持多个存档槽位
- 添加自动保存机制

关联 Issue #12"
```

### 场景和资源示例

```bash
# 场景相关
git commit -m "scene：创建战斗场景并配置相机"

# 资源相关
git commit -m "asset：导入角色动画资源包"

# UI 相关
git commit -m "ui：完成主菜单界面设计"

# 音频相关
git commit -m "audio：添加脚步声和跳跃音效"
```

### 游戏开发示例

```bash
# 游戏玩法
git commit -m "gameplay：实现道具拾取和使用系统"

# 关卡设计
git commit -m "level：设计并实现第三关卡"

# 配置调整
git commit -m "config：平衡敌人血量和伤害数值"

# 插件集成
git commit -m "plugin：添加粒子效果插件"
```

### 重构和优化示例

```bash
# 代码重构
git commit -m "refactor：重构角色状态机逻辑"

# 性能优化
git commit -m "perf：优化大量敌人时的渲染性能"

# 代码格式
git commit -m "style：统一 GDScript 代码风格"
```

## 多类型改动的处理

### 问题场景

有时一次开发工作可能同时包含多种类型的改动，例如：
- 既修复了 Bug，又添加了新功能
- 既重构了代码，又优化了性能
- 既更新了场景，又修改了脚本

### 推荐做法：拆分提交（强烈推荐）⭐

**原则**：一次提交只做一件事，保持提交历史清晰

```bash
# ❌ 不推荐：混合提交
git commit -m "fix + feat：修复跳跃 Bug 并添加二段跳功能"

# ✅ 推荐：拆分成两次提交
git add PlayerController.gd  # 只添加修复 Bug 的部分
git commit -m "fix：修复角色跳跃时的碰撞检测问题"

git add PlayerController.gd  # 添加新功能的部分
git commit -m "feat：实现角色二段跳功能"
```

### 拆分提交的优势

1. **清晰的历史记录**：每次提交目的明确，便于回溯
2. **便于代码审查**：审查者可以分别查看不同类型的改动
3. **灵活的回滚**：可以单独回滚某个功能或修复，而不影响其他改动
4. **更好的协作**：团队成员能快速理解每次提交的意图
5. **自动化工具友好**：CI/CD 和版本管理工具能更好地处理

### 如何拆分提交

#### 方法一：使用 git add -p（交互式暂存）

```bash
# 交互式选择要暂存的代码块
git add -p PlayerController.gd

# 选择修复 Bug 的部分，提交
git commit -m "fix：修复角色跳跃时的碰撞检测问题"

# 暂存剩余的新功能代码
git add PlayerController.gd
git commit -m "feat：实现角色二段跳功能"
```

#### 方法二：分步开发和提交

```bash
# 第一步：先完成并提交 Bug 修复
# 修改代码...
git add PlayerController.gd
git commit -m "fix：修复角色跳跃时的碰撞检测问题"

# 第二步：再开发并提交新功能
# 继续修改代码...
git add PlayerController.gd
git commit -m "feat：实现角色二段跳功能"
```

#### 方法三：使用临时分支

```bash
# 创建临时分支保存当前工作
git stash

# 只恢复修复 Bug 的部分并提交
git stash pop
# 手动撤销新功能代码，只保留 Bug 修复
git add PlayerController.gd
git commit -m "fix：修复角色跳跃时的碰撞检测问题"

# 恢复新功能代码并提交
# 重新添加新功能代码...
git add PlayerController.gd
git commit -m "feat：实现角色二段跳功能"
```

### 特殊情况：确实无法拆分时

如果改动确实紧密耦合、无法拆分（这种情况应该很少见），可以使用以下方式：

#### 方式一：选择主要类型 + 详细描述（推荐）

```bash
git commit -m "feat：实现角色二段跳功能

- 添加二段跳的核心逻辑
- 修复原有跳跃系统的碰撞检测问题
- 优化跳跃动画的过渡效果

本次提交包含了功能开发和 Bug 修复，因为二段跳的实现
依赖于修复原有跳跃系统的碰撞问题。"
```

#### 方式二：使用多行描述分别说明

```bash
git commit -m "feat：重构并优化角色移动系统

功能改进：
- 实现新的移动状态机
- 添加冲刺功能

Bug 修复：
- 修复移动时的抖动问题
- 修复斜坡上的滑动问题

性能优化：
- 减少物理计算频率
- 优化碰撞检测算法"
```

### 什么时候应该拆分？

| 情况 | 是否拆分 | 原因 |
|------|---------|------|
| 修复 Bug + 添加新功能 | ✅ 应该拆分 | 两个独立的逻辑改动 |
| 重构代码 + 性能优化 | ✅ 应该拆分 | 目的不同，影响范围不同 |
| 添加场景 + 编写脚本 | ✅ 应该拆分 | 不同类型的文件改动 |
| 修复 Bug + 添加该 Bug 的测试 | ❌ 可以合并 | 测试是修复的一部分 |
| 重构 + 重构后必需的修复 | ❌ 可以合并 | 修复是重构的直接结果 |
| 添加功能 + 更新相关文档 | ⚠️ 视情况而定 | 简单文档可合并，复杂文档应拆分 |

## 注意事项

1. **使用中文冒号**：类型后使用中文冒号 `：` 而非英文冒号 `:`
2. **简短明确**：描述应简洁明了，一般不超过 50 个字符
3. **动词开头**：描述部分使用动词开头，如"添加"、"修复"、"更新"等
4. **一次提交一个改动**：每次提交应该只包含一个逻辑改动（最重要的原则）⭐
5. **详细描述**：对于复杂的改动，应该添加详细描述说明改动的原因和影响
6. **避免混合类型**：不要在一次提交中混合多种类型的改动（如 fix + feat）
7. **先提交修复，再提交功能**：如果必须在同一开发周期内完成，优先提交 Bug 修复
8. **使用 git add -p**：善用交互式暂存来精确控制每次提交的内容
9. **提交前自查**：问自己"这次提交是否只做了一件事？"
10. **保持提交原子性**：每次提交都应该是完整的、可独立运行的改动

## 分支命名规范

```bash
# 功能分支
feature/角色系统
feature/存档功能

# 修复分支
fix/碰撞检测
fix/音频播放

# 开发分支
dev
develop

# 发布分支
release/v1.0.0
release/v1.1.0
```

## 常见问题 FAQ

### Q1: 我同时修复了 3 个小 Bug，应该分 3 次提交吗？

**A**: 视情况而定：
- 如果是**相关的 Bug**（同一个系统/模块），可以合并为一次提交
- 如果是**不相关的 Bug**（不同系统/模块），应该分别提交

```bash
# ✅ 相关 Bug 可以合并
git commit -m "fix：修复角色移动系统的多个问题

- 修复在斜坡上的滑动问题
- 修复跳跃时的速度计算错误
- 修复冲刺时的方向判断问题"

# ✅ 不相关 Bug 应该拆分
git commit -m "fix：修复角色跳跃时的碰撞检测问题"
git commit -m "fix：修复 UI 菜单的按钮响应延迟"
git commit -m "fix：修复音频播放时的内存泄漏"
```

### Q2: 我在开发新功能时发现了 Bug，应该怎么办？

**A**: 推荐流程：
1. 暂存当前新功能的代码（`git stash`）
2. 修复 Bug 并提交
3. 恢复新功能代码继续开发
4. 完成后提交新功能

```bash
# 保存当前工作
git stash save "WIP: 开发二段跳功能"

# 修复 Bug
git add PlayerController.gd
git commit -m "fix：修复角色跳跃时的碰撞检测问题"

# 恢复工作并继续开发
git stash pop
# 继续开发...
git commit -m "feat：实现角色二段跳功能"
```

### Q3: 重构代码时顺便优化了性能，算一次提交吗？

**A**: 应该拆分：
- 重构（`refactor`）：改变代码结构但不改变行为
- 优化（`perf`）：改善性能表现

```bash
# ✅ 拆分提交
git commit -m "refactor：重构敌人 AI 状态机逻辑"
git commit -m "perf：优化敌人 AI 的路径计算性能"
```

### Q4: 我应该多久提交一次？

**A**: 遵循以下原则：
- ✅ 完成一个**完整的逻辑单元**就提交
- ✅ 代码能够**正常运行**时提交
- ✅ 下班前提交当天的工作进度
- ❌ 不要等到功能完全完成才提交（可能跨越多天）
- ❌ 不要提交无法运行的代码

### Q5: 提交信息写错了怎么办？

**A**: 使用 `git commit --amend` 修改最后一次提交：

```bash
# 修改最后一次提交信息
git commit --amend -m "fix：修复角色跳跃时的碰撞检测问题"

# 如果已经推送到远程，需要强制推送（谨慎使用）
git push --force-with-lease
```

⚠️ **注意**：只修改未推送或未被他人使用的提交！

## 工具推荐

- **Commitizen**: 交互式提交信息生成工具
- **Git Hooks**: 使用 pre-commit 钩子自动检查提交格式
- **Conventional Commits**: 遵循约定式提交规范
- **Git GUI 工具**: GitKraken、SourceTree 等支持可视化暂存部分代码

## 总结

记住这些核心原则：

1. ⭐ **一次提交只做一件事** - 最重要的原则
2. 🔀 **能拆分就拆分** - 保持提交历史清晰
3. 🎯 **提交要有意义** - 每次提交都应该是完整的改动
4. 📝 **描述要清晰** - 让别人（和未来的自己）能快速理解
5. 🚫 **避免混合类型** - 不要 fix + feat 混在一起

**好的提交习惯 = 清晰的项目历史 = 高效的团队协作**
