# 前端分支提交与合并防覆盖操作规范

## 适用范围

本文档适用于 `legal-platform-frontend` 前端仓库，重点解决以下高频问题：

- 本地有未提交改动时，如何安全合并别人的分支
- `main`、`wren-dev`、`shiy-dev` 等并行开发分支之间，如何避免代码被覆盖
- 为什么“提交历史已经包含某个 commit”，但代码内容实际丢了
- 如何做正确的提交、推送、PR 和合并后校验

---

## 一、核心原则

### 1. 不要在脏工作区直接合并

合并前必须先执行：

```bash
git status
```

如果存在未提交改动，必须先处理：

- 能独立提交的，先提交
- 暂时不想提交的，先 `stash`

例如：

```bash
git stash -u
```

否则很容易出现：

- 合并过程把本地改动混进别人的改动
- 冲突解决时误选本地旧代码
- 最终提交混杂多个需求，后续难以回溯

### 2. 不要把“历史包含”误判成“功能保留”

以下命令只能说明“某个提交进入过历史”：

```bash
git branch --contains <commit>
```

但它**不能说明这次提交改过的内容现在还保留在代码树里**。

实际开发中常见情况是：

- A 分支的提交先合入 `main`
- 后续 `main` 再合到 B 分支
- 冲突时错误选择了旧版本
- 结果：`commit` 在历史里，但 `patch` 被覆盖没了

所以合并后必须额外做“内容保留校验”。

### 3. 冲突处理不能图快全选一边

遇到冲突时，不能默认：

- 全部选 `ours`
- 全部选 `theirs`

必须逐文件判断：

- 哪些是对方新增能力
- 哪些是我方已有修复
- 哪些要手工拼接

尤其是以下类型文件最容易被误覆盖：

- 页面组件
- API 路由
- 配置文件
- 公共组件
- 菜单/路由白名单

### 4. 合并完成后必须做“保留性校验”

至少要检查三件事：

1. 提交历史是否进入
2. 关键文件是否仍保留目标改动
3. 关键标识是否还能在代码中搜到

---

## 二、标准操作流程

## 1. 合并别人的分支到自己分支

假设目标是：把 `origin/shiy-dev` 合到当前 `wren-dev`

### 第一步：同步远程

```bash
git fetch origin
```

### 第二步：检查本地工作区

```bash
git status
```

如果有未提交改动：

```bash
git stash -u
```

或者先拆分提交。

### 第三步：确认自己当前所在分支

```bash
git branch --show-current
```

必须确认当前就在 `wren-dev`，不要站错分支。

### 第四步：执行合并

```bash
git merge --no-ff origin/shiy-dev
```

如果要明确记录来源，建议使用：

```bash
git merge --no-ff origin/shiy-dev -m "merge: sync origin/shiy-dev into wren-dev"
```

### 第五步：如果冲突，逐文件处理

处理完冲突后：

```bash
git add <冲突文件>
git commit
```

### 第六步：恢复之前的 stash

```bash
git stash pop
```

如果 `stash pop` 冲突，不要慌，继续按文件处理。

---

## 2. 合并 `main` 到自己分支

目标：保持 `wren-dev` 跟上主线进度

标准步骤：

```bash
git fetch origin
git status
git stash -u          # 如果有本地未提交改动
git merge --no-ff origin/main -m "merge: sync origin/main into wren-dev"
git stash pop         # 如果前面 stash 了
```

说明：

- 不要直接把 `main` 切到当前脏工作区里操作
- 如果本地 `main` 有 worktree，优先在独立 worktree 同步
- 当前主开发工作区建议长期停留在 `wren-dev`

---

## 3. 合并后做“内容保留校验”

这是最关键的一步。

### 先检查目标提交是否进入历史

```bash
git branch --contains <commit>
```

### 再检查关键文件内容是否保住

```bash
git diff <commit>..HEAD -- <关键文件>
```

如果看到的是“反向撤销”差异，说明：

- 历史里有这个提交
- 但代码内容被后续 merge 覆盖掉了

### 再搜关键符号

例如某次改动新增了：

- `ENTRY_MODULE_ROUTE_OPTIONS`
- `FormSelect`
- `isAllowedEntryModuleRoutePath`

就应该执行：

```bash
rg "ENTRY_MODULE_ROUTE_OPTIONS|FormSelect|isAllowedEntryModuleRoutePath" .
```

如果关键标识不在，说明功能实际上没有保住。

---

## 三、发现“历史包含但代码没了”怎么办

这是本项目已经真实发生过的情况。

## 处理原则

不要重新大范围 merge。

正确做法是：

- 精确定位丢失的是哪些文件
- 只恢复这些文件
- 单独提交

### 推荐命令

```bash
git restore --source=<目标提交> -- <文件1> <文件2> ...
```

例如：

```bash
git restore --source=2b912ca -- \
  app/(audit)/documents/list/DocumentsListClient.tsx \
  app/(audit)/entry-modules/new/EntryModuleNewClient.tsx \
  app/api/pdf-proxy/route.ts \
  components/layout/Sidebar.tsx \
  lib/config/entry-module-route-options.ts
```

然后单独提交：

```bash
git add <这些文件>
git commit -m "fix: restore shiy-dev entry route whitelist changes"
git push origin wren-dev
```

这种方式最安全，且不会影响你当前其他本地需求改动。

---

## 四、提交规范

## 1. 一个提交只解决一类问题

不要把以下内容混在一个 commit：

- 聊天功能修复
- 公文审查 UI 收敛
- 合同模板页面开发
- 分支恢复补丁

应该拆成：

- `fix: remove govdoc inspector file info tab`
- `fix: restore shiy-dev entry route whitelist changes`
- `feat: add contract template search results page`

## 2. 提交前先看范围

提交前务必执行：

```bash
git status
git diff --stat
```

如果只想提交部分文件：

```bash
git add <目标文件>
git commit -m "<message>"
```

不要图省事直接：

```bash
git add .
```

除非你确认工作区所有改动都属于同一件事。

## 3. 提交信息规范

推荐格式：

```text
feat: 新增功能
fix: 修复问题
refactor: 重构实现
merge: 分支合并
docs: 文档更新
```

示例：

- `feat: stabilize rag chat conversation lifecycle`
- `fix: remove govdoc inspector file info tab`
- `fix: restore shiy-dev entry route whitelist changes`
- `merge: sync origin/main into wren-dev`

---

## 五、推送规范

推送前先确认：

```bash
git status
git log --oneline --max-count=5
```

再执行：

```bash
git push origin wren-dev
```

如果本地还有未提交改动，不影响推送已提交的 commit，但要明确知道：

- 已提交内容会推上去
- 未提交内容不会推上去

不要误以为“工作区里看到的所有代码”都已经在远程。

---

## 六、PR 规范

PR 标题必须说明“做了什么”，不要只写模块名。

推荐示例：

- `恢复入口模块跳转路径白名单与 FormSelect 收敛改动`
- `修复 RAG 对话会话生命周期、自动重命名刷新与列表状态问题`

PR 描述建议固定包含：

### 1. 背景

为什么要改。

### 2. 本次改动

具体改了哪些点。

### 3. 影响范围

改到了哪些页面、接口、组件、模块。

### 4. 验证建议

告诉审核人怎么测。

### 5. 特别说明

如果是“恢复被覆盖改动”，要明确写出来，避免评审人误解成重复开发。

---

## 七、推荐命令清单

### 检查工作区

```bash
git status
git diff --stat
```

### 同步远程

```bash
git fetch origin
```

### 暂存本地未提交改动

```bash
git stash -u
git stash pop
```

### 合并主线或他人分支

```bash
git merge --no-ff origin/main
git merge --no-ff origin/shiy-dev
```

### 检查某个提交是否进入历史

```bash
git branch --contains <commit>
```

### 检查关键 patch 是否仍保留

```bash
git diff <commit>..HEAD -- <关键文件>
```

### 精确恢复某次提交改动

```bash
git restore --source=<commit> -- <文件列表>
```

### 只提交指定文件

```bash
git add <文件列表>
git commit -m "<message>"
```

### 推送当前分支

```bash
git push origin wren-dev
```

---

## 八、结论

以后判断一次合并是否真正成功，不能只看：

- 分支图里有没有那个 commit

还必须同时看：

- 关键文件内容还在不在
- 关键标识还能不能搜到
- 最终页面行为是不是正确

一句话总结：

> 合并成功的标准，不是“历史里有 commit”，而是“当前代码树里还保留对应 patch，并且功能行为正确”。

