# Git、资源与持久化

本参考用于新建仓库、设计 `.gitignore`、处理图片／文件或决定业务数据存放位置。目标是让源码、迁移和配置契约可追踪，同时把运行时数据、二进制资源和秘密留在适合它们的系统中。

多人分支协作、本地与远端的关系、冲突和回退见[团队 Git 协作](team-git-collaboration.md)。

## 初始化和提交

新项目先用 `git --version` 确认 Git CLI 可用；缺失时按当前操作系统或团队镜像的标准方式安装，不能下载来历不明的二进制。再检查目录是否已位于父级 Git 仓库中。只有确认没有可复用的仓库边界时，才在项目根目录初始化 Git；通常使用项目约定的默认分支，例如：

```bash
git init -b main
```

初始化后立即建立 `.gitignore`、`AGENTS.md` 和必要配置，再进行首次有意义的提交。不要修改用户的全局 Git 设置。提交需要作者身份时，优先使用已有仓库或组织配置；没有可靠的姓名和邮箱时不能编造，应由用户提供后再写入仓库级或全局配置。

每项完整改动完成最小必要验证后，默认创建一次原子本地提交：

1. 用 `git status --short` 和 `git diff` 区分本任务改动与已有工作；
2. 只暂存本任务文件，并复核 `git diff --cached`；
3. 确认没有秘密、用户数据、运行时二进制或生成垃圾；
4. 使用描述实际行为变化的简洁提交信息提交。

不要提交每次保存、明显无法运行的中间状态或其他人的未完成改动。创建本地提交不授权推送、合并、发布或改远端设置。

## `.gitignore` 设计

`.gitignore` 从实际框架、工具和运行目录推导，不从其他项目整份复制。Next.js／TypeScript 项目通常从以下基线开始，再按实际工具增删：

```gitignore
# dependencies and builds
node_modules/
.next/
out/
dist/
.turbo/
coverage/

# tests and logs
playwright-report/
test-results/
*.log

# local runtime configuration
.env
.env.*
!.env.example
!.env.template

# runtime data and uploaded files
data/
uploads/
storage/
tmp/
*.sqlite
*.sqlite3
*.db
*.dump

# editor and operating-system files
.DS_Store
Thumbs.db
.idea/
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
```

关键规则：

- 不要全局忽略 `*.json`：`package.json`、TypeScript 配置、组件配置、静态翻译和受控测试夹具可能属于源码。
- 不要全局忽略 `*.sql`：Drizzle／Prisma 生成并审阅过的迁移 SQL 必须提交。
- 依赖锁文件必须提交；不能把 `pnpm-lock.yaml`、`package-lock.json` 或实际使用的其他锁文件加入忽略。
- 若仓库决定共享某些编辑器设置，只对白名单文件解除忽略；不要提交用户个人工作区状态。
- Docker 构建上下文另行配置 `.dockerignore`，至少排除 `.git`、依赖目录、构建输出、测试产物、运行时配置、日志、本地数据和上传目录。

`.gitignore` 不能移除已追踪文件，也不能代替提交审阅。首次提交前检查 `git status --short --ignored`；后续提交仍需复核暂存清单。

## 二进制文件与对象存储

二进制文件不直接进入 Git，包括用户上传、运行时生成文件、项目图片、字体、音视频、PDF、Office 文档、压缩包、模型文件、数据库文件、数据库导出和构建制品；体积小也不例外。Git LFS 不是绕过这一规则的默认方案。源码、可审阅的文本 SVG、配置、资源清单及处理脚本仍可按项目规则版本化；网页资源使用对象存储，构建制品和备份使用各自受管理的存储。

网页资源的格式、压缩、缓存和跨机器可复现要求见[静态资源与对象存储](../performance/static-assets.md)。

产品需要图片或文件时，使用选定的 OSS／S3 兼容对象存储，并建立真实服务端链路：

- Bucket 默认私有，下载通过服务端授权或短期签名 URL；
- 对象键由服务端生成，不信任原始文件名作为路径或权限；
- 校验声明类型、实际内容、大小和允许的文件类别；
- PostgreSQL 保存对象键、所有者、用途、MIME、大小、校验值、状态和必要时间戳；
- 数据库记录是归属和可见性的权威，对象公开 URL 不是权限证明；
- 上传、业务写入、重试和删除要有明确的幂等与失败清理语义；无法确认数据库是否已引用对象时优先保留并记录诊断，不能冒险删除。

本地开发可以使用与生产协议兼容的受控测试 Bucket 或可复现的本地 S3 兼容服务，但不能把本地上传目录提交到 Git，也不能依赖某台电脑上的专有路径或文件。没有任何图片／文件需求时，不预建空的 OSS 适配层。

## JSON 与 SQL 的边界

用户、账号、会话、订单、任务、内容状态、权限、处理进度及其他运行时可变业务事实必须进入 PostgreSQL，并由迁移、约束、事务和授权保护。禁止通过读取、改写仓库内 JSON 文件来模拟数据库，也禁止把 JSON 文件锁当作并发控制。

JSON 仍可用于：

- `package.json`、TypeScript 或工具配置；
- 不在运行时写回的静态翻译、常量和受控内容资产；
- 明确隔离的测试 fixture；
- 导入／导出或一次性迁移的中间格式。

需要将静态种子转成业务记录时，使用可审阅、可重复执行的 seed 或迁移脚本写入 PostgreSQL；应用运行时从数据库读取，不把源 JSON 当作第二个事实来源。半结构化字段可以使用 PostgreSQL `jsonb`，但仍需 Schema 级约束、应用校验、索引策略和清晰的数据所有权。
