# Git 最佳实践

## .gitignore 配置说明

本项目的 `.gitignore` 文件经过精心配置，确保只提交必要的文件到版本控制系统。

---

## 🚫 被忽略的文件类型

### Python 相关

**缓存文件：**
- `__pycache__/` - Python 字节码缓存
- `*.pyc`, `*.pyo`, `*.pyd` - 编译的 Python 文件
- `.pytest_cache/` - pytest 缓存
- `.mypy_cache/` - mypy 类型检查缓存
- `.ruff_cache/` - ruff linter 缓存

**测试覆盖率：**
- `.coverage` - 覆盖率数据文件
- `htmlcov/` - HTML 覆盖率报告
- `coverage.xml` - XML 覆盖率报告

**构建产物：**
- `dist/` - 发布包目录
- `build/` - 构建临时目录
- `*.egg-info/` - 包元数据

**虚拟环境：**
- `.venv/`, `venv/`, `env/` - 虚拟环境目录

### IDE 配置

- `.idea/` - PyCharm 配置
- `.vscode/` - VS Code 配置
- `*.sublime-project`, `*.sublime-workspace` - Sublime Text
- `*.swp`, `*.swo` - Vim 临时文件

### 操作系统文件

**macOS：**
- `.DS_Store` - Finder 配置
- `.AppleDouble` - 资源分支
- `._*` - 临时文件

**Windows：**
- `Thumbs.db` - 缩略图缓存
- `Desktop.ini` - 文件夹配置

**Linux：**
- `*~` - 备份文件
- `.directory` - KDE 文件夹配置

### 敏感信息

**环境变量：**
- `.env` - ⚠️ 包含敏感配置，绝不提交！
- `.env.local`, `.env.*.local` - 本地环境配置

**凭证和密钥：**
- `.pypirc` - ⚠️ PyPI API token，绝不提交！
- `*.key`, `*.pem` - 私钥文件
- `credentials.json`, `secrets.json` - 凭证文件

### 临时文件

- `*.log` - 日志文件
- `*.tmp`, `*.temp` - 临时文件
- `*.bak`, `*.backup` - 备份文件

---

## ✅ 应该提交的文件

### 源代码
- `src/` - 所有源代码
- `tests/` - 测试代码
- `scripts/` - 实用脚本

### 配置文件
- `pyproject.toml` - 项目配置
- `uv.lock` - 依赖锁定文件
- `.python-version` - Python 版本要求
- `.gitignore` - Git 忽略配置
- `.gitattributes` - Git 属性配置

### 文档
- `README.md` - 项目说明
- `CHANGELOG.md` - 变更日志
- `LICENSE` - 许可证
- `docs/` - 所有文档

### 示例和模板
- `.env.example` - ✅ 环境变量示例（不包含敏感信息）
- `examples/` - 示例代码

### CI/CD
- `.github/` - GitHub Actions 配置

---

## 📋 检查清单

在提交前，请确保：

### ✅ 应该做的

- [ ] 源代码已添加
- [ ] 测试代码已添加
- [ ] 文档已更新
- [ ] `pyproject.toml` 已更新
- [ ] `CHANGELOG.md` 已更新
- [ ] `.env.example` 已更新（如果添加了新的环境变量）

### ❌ 不应该做的

- [ ] 没有提交 `.env` 文件
- [ ] 没有提交 `.pypirc` 文件
- [ ] 没有提交 IDE 配置文件（`.idea/`, `.vscode/`）
- [ ] 没有提交缓存文件（`__pycache__/`, `.pytest_cache/`）
- [ ] 没有提交构建产物（`dist/`, `build/`）
- [ ] 没有提交虚拟环境（`.venv/`）
- [ ] 没有提交测试覆盖率报告（`htmlcov/`, `.coverage`）
- [ ] 没有提交系统文件（`.DS_Store`, `Thumbs.db`）

---

## 🔍 验证 .gitignore

### 检查当前状态

```bash
# 查看未跟踪的文件
git status

# 查看被忽略的文件
git status --ignored

# 检查特定文件是否被忽略
git check-ignore -v .env
```

### 测试 .gitignore 规则

```bash
# 查看 .env 是否被忽略
git check-ignore .env
# 如果被忽略，会输出：.env

# 查看 .env.example 是否被忽略
git check-ignore .env.example
# 如果没有输出，说明不被忽略（正确）
```

---

## 🛠️ 常见问题

### Q1: 如何忽略已经提交的文件？

如果不小心提交了敏感文件：

```bash
# 1. 从 Git 中删除（但保留本地文件）
git rm --cached .env

# 2. 提交删除操作
git commit -m "Remove .env from version control"

# 3. 确保 .env 在 .gitignore 中
echo ".env" >> .gitignore

# 4. 提交 .gitignore 更新
git add .gitignore
git commit -m "Update .gitignore to exclude .env"
```

⚠️ **重要**：即使从 Git 删除，文件历史仍然存在！如果是敏感信息，需要：
1. 重新生成密钥/token
2. 使用 `git filter-branch` 或 BFG Repo-Cleaner 清理历史

### Q2: .env.example 和 .env 的区别？

| 文件 | 用途 | 是否提交 | 内容 |
|------|------|---------|------|
| `.env` | 实际环境变量 | ❌ 不提交 | 包含真实的密钥和配置 |
| `.env.example` | 环境变量模板 | ✅ 提交 | 只包含示例值，不含敏感信息 |

**示例：**

`.env` (不提交):
```env
API_KEY=sk-real-key-1234567890abcdef
DATABASE_URL=postgresql://user:realpassword@localhost/db
```

`.env.example` (提交):
```env
API_KEY=your-api-key-here
DATABASE_URL=postgresql://user:password@localhost/dbname
```

### Q3: 如何查看被忽略的文件？

```bash
# 查看所有被忽略的文件
git status --ignored

# 只查看被忽略的文件（不显示其他状态）
git status --ignored --porcelain | grep "^!!"

# 查看特定目录下被忽略的文件
git status --ignored -- src/
```

### Q4: 如何强制添加被忽略的文件？

```bash
# 不推荐，但如果确实需要：
git add -f .env

# 更好的做法是检查 .gitignore 是否正确
```

### Q5: uv.lock 应该提交吗？

✅ **是的！** `uv.lock` 应该提交。

**原因：**
- 确保团队成员使用相同版本的依赖
- 确保 CI/CD 环境一致性
- 可重现的构建

类似的文件：
- `package-lock.json` (npm)
- `yarn.lock` (Yarn)
- `poetry.lock` (Poetry)
- `Pipfile.lock` (Pipenv)

---

## 📝 最佳实践

### 1. 定期清理

```bash
# 清理被忽略的文件
git clean -fdX

# 预览会被清理的文件（不实际删除）
git clean -fdXn
```

### 2. 全局 .gitignore

对于个人偏好的忽略规则（如 IDE 配置），使用全局配置：

```bash
# 配置全局 .gitignore
git config --global core.excludesfile ~/.gitignore_global

# 编辑全局 .gitignore
echo ".DS_Store" >> ~/.gitignore_global
echo ".vscode/" >> ~/.gitignore_global
```

### 3. 项目级 vs 全局

| 类型 | 项目 .gitignore | 全局 .gitignore |
|------|----------------|----------------|
| Python 缓存 | ✅ | ❌ |
| 构建产物 | ✅ | ❌ |
| IDE 配置 | ⚠️ 可选 | ✅ 推荐 |
| OS 文件 | ⚠️ 可选 | ✅ 推荐 |

### 4. 提交前检查

```bash
# 查看将要提交的文件
git status

# 查看文件差异
git diff

# 查看暂存区的差异
git diff --staged

# 检查是否有敏感信息
grep -r "password\|secret\|key" --include="*.py" src/
```

---

## 🔒 安全提示

### 永远不要提交：

1. ❌ **密码和密钥**
   - API keys
   - 数据库密码
   - SSH 私钥
   - OAuth tokens

2. ❌ **凭证文件**
   - `.env`
   - `.pypirc`
   - `credentials.json`
   - `secrets.json`

3. ❌ **个人信息**
   - 邮箱地址（在配置文件中）
   - 真实的域名和 IP
   - 个人访问令牌

### 如果不小心提交了敏感信息：

1. 立即轮换密钥/凭证
2. 从 Git 历史中移除（使用 BFG 或 git-filter-repo）
3. 通知相关人员
4. 更新 `.gitignore`
5. 审查安全日志

---

## 📚 参考资源

- [GitHub .gitignore 模板](https://github.com/github/gitignore)
- [Git 官方文档](https://git-scm.com/docs/gitignore)
- [Python .gitignore 最佳实践](https://github.com/github/gitignore/blob/main/Python.gitignore)

---

## 🎯 快速参考

```bash
# 查看状态
git status
git status --ignored

# 检查忽略规则
git check-ignore -v <file>

# 清理忽略的文件
git clean -fdX

# 从 Git 中移除但保留本地文件
git rm --cached <file>

# 强制添加被忽略的文件（不推荐）
git add -f <file>
```

---

**记住：** 当不确定某个文件是否应该提交时，默认选择不提交，并咨询团队成员！
