Final rebrand: rename remaining Rust source file to complete the gsd → forge transition. All parser references already use forge_parser after earlier commits. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
186 lines
7.7 KiB
Markdown
186 lines
7.7 KiB
Markdown
# Git 策略
|
||
|
||
SF 使用 git 来实现 milestone 隔离,以及每个 milestone 内部的顺序提交。你可以通过 **isolation mode** 控制工作发生在哪里。整个策略是自动化的,你不需要手工管理分支。
|
||
|
||
## 隔离模式
|
||
|
||
SF 支持三种隔离模式,通过 `git.isolation` 偏好设置:
|
||
|
||
| 模式 | 工作目录 | 分支 | 适用场景 |
|
||
|------|----------|------|----------|
|
||
| `worktree`(默认) | `.sf/worktrees/<MID>/` | `milestone/<MID>` | 大多数项目,milestones 之间文件完全隔离 |
|
||
| `branch` | 项目根目录 | `milestone/<MID>` | 子模块较多、worktree 表现不佳的仓库 |
|
||
| `none` | 项目根目录 | 当前分支(不建 milestone 分支) | 热重载工作流中,文件隔离会破坏开发工具的场景 |
|
||
|
||
### `worktree` 模式(默认)
|
||
|
||
每个 milestone 都会在 `.sf/worktrees/<MID>/` 下拥有自己的 git worktree,对应一个 `milestone/<MID>` 分支。所有执行都发生在该 worktree 中。完成后,worktree 会被 squash merge 回主分支,形成一个干净的提交,然后清理对应 worktree 和分支。
|
||
|
||
这提供了完整的文件隔离,某个 milestone 的变更不会干扰你的主工作副本。
|
||
|
||
### `branch` 模式
|
||
|
||
工作直接在项目根目录中的 `milestone/<MID>` 分支上进行,不会创建 worktree。完成后,该分支会被合并回主分支(是 squash merge 还是普通 merge 由 `merge_strategy` 控制)。
|
||
|
||
当 worktree 会带来问题时使用它,例如:子模块较多的仓库、包含硬编码路径的仓库、或者 worktree symlink 表现异常的环境。
|
||
|
||
### `none` 模式
|
||
|
||
工作直接发生在当前分支。没有 worktree,也没有 milestone 分支。SF 依然会按顺序提交,并使用 conventional commit message,但不会提供分支级隔离。
|
||
|
||
适用于热重载工作流中“文件隔离会破坏开发工具”的情况(例如只能监视项目根目录的文件监听器),或者很小的项目里不值得承担分支开销的情况。
|
||
|
||
## 分支模型(worktree 模式)
|
||
|
||
```
|
||
main ─────────────────────────────────────────────────────────
|
||
│ ↑
|
||
└── milestone/M001 (worktree) ────────────────────────┘
|
||
commit: feat: core types
|
||
commit: feat: markdown parser
|
||
commit: feat: file writer
|
||
commit: docs: workflow docs
|
||
...
|
||
→ squash-merged to main as single commit
|
||
```
|
||
|
||
在 **branch 模式** 下,流程相同,只是工作发生在项目根目录而不是独立的 worktree 目录。
|
||
|
||
在 **none 模式** 下,提交直接落到当前分支,不会创建 milestone 分支,也不需要合并步骤。
|
||
|
||
### 并行 worktrees
|
||
|
||
如果启用了 [并行编排](./parallel-orchestration.md),多个 milestones 可以同时运行在各自独立的 worktree 中:
|
||
|
||
```
|
||
main ──────────────────────────────────────────────────────────
|
||
│ ↑ ↑
|
||
├── milestone/M002 (worktree) ─────────┘ │
|
||
│ commit: feat: auth types │
|
||
│ commit: feat: JWT middleware │
|
||
│ → squash-merged first │
|
||
│ │
|
||
└── milestone/M003 (worktree) ────────────────────────┘
|
||
commit: feat: dashboard layout
|
||
commit: feat: chart components
|
||
→ squash-merged second
|
||
```
|
||
|
||
每个 worktree 都工作在自己的分支和自己的提交历史上。为了避免冲突,合并会顺序进行。
|
||
|
||
### 关键特性
|
||
|
||
- **单分支顺序提交**:没有按 slice 单独分支,也不会在单个 milestone 内产生合并冲突
|
||
- **Squash merge 到主分支**:在 worktree 和 branch 模式下,所有提交最终都会以一个干净的提交压缩到主分支(可通过 `merge_strategy` 配置)
|
||
|
||
### 提交格式
|
||
|
||
提交使用 conventional commit 格式,并在 trailer 中带上 SF 元数据:
|
||
|
||
```
|
||
feat: core type definitions
|
||
|
||
SF-Task: M001/S01/T01
|
||
|
||
feat: markdown parser for plan files
|
||
|
||
SF-Task: M001/S01/T02
|
||
```
|
||
|
||
## Worktree 管理
|
||
|
||
以下特性仅适用于 **worktree 模式**。
|
||
|
||
### 自动(自动模式)
|
||
|
||
自动模式会自动创建并管理 worktrees:
|
||
|
||
1. milestone 启动时,在 `.sf/worktrees/<MID>/` 创建 worktree,并切到 `milestone/<MID>` 分支
|
||
2. 将 `.sf/milestones/` 下的规划产物复制到该 worktree
|
||
3. 所有执行都发生在 worktree 内部
|
||
4. milestone 完成后,把该 worktree squash merge 回集成分支
|
||
5. 删除 worktree 和对应分支
|
||
|
||
### 手动
|
||
|
||
使用 `/worktree`(或 `/wt`)命令手动管理 worktree:
|
||
|
||
```
|
||
/worktree create
|
||
/worktree switch
|
||
/worktree merge
|
||
/worktree remove
|
||
```
|
||
|
||
## 工作流模式
|
||
|
||
如果不想逐个配置 git 设置,可以通过 `mode` 获得一组更合理的默认值:
|
||
|
||
```yaml
|
||
mode: solo # 个人项目:自动推送、squash、简单 ID
|
||
mode: team # 共享仓库:唯一 ID、推送分支、预合并检查
|
||
```
|
||
|
||
| 设置 | `solo` | `team` |
|
||
|---|---|---|
|
||
| `git.auto_push` | `true` | `false` |
|
||
| `git.push_branches` | `false` | `true` |
|
||
| `git.pre_merge_check` | `false` | `true` |
|
||
| `git.merge_strategy` | `"squash"` | `"squash"` |
|
||
| `git.isolation` | `"worktree"` | `"worktree"` |
|
||
| `git.commit_docs` | `true` | `true` |
|
||
| `unique_milestone_ids` | `false` | `true` |
|
||
|
||
Mode 默认值的优先级最低,任何显式偏好设置都会覆盖它们。例如,`mode: solo` 配合 `git.auto_push: false`,就表示除了自动推送以外,其它行为都沿用 solo 的默认配置。
|
||
|
||
已有但未设置 `mode` 的配置会保持原样,不会被自动注入新默认值。
|
||
|
||
## Git 偏好设置
|
||
|
||
可以在偏好设置中配置 git 行为:
|
||
|
||
```yaml
|
||
git:
|
||
auto_push: false # 提交后推送
|
||
push_branches: false # 推送 milestone 分支
|
||
remote: origin
|
||
snapshots: false # WIP 快照提交
|
||
pre_merge_check: false # 合并前校验
|
||
commit_type: feat # 覆盖提交类型前缀
|
||
main_branch: main # 主分支名称
|
||
commit_docs: true # 将 .sf/ 提交到 git
|
||
isolation: worktree # "worktree"、"branch" 或 "none"
|
||
auto_pr: false # milestone 完成时自动创建 PR
|
||
pr_target_branch: develop # PR 目标分支(默认 main)
|
||
```
|
||
|
||
### 自动创建 Pull Request
|
||
|
||
对于使用 Gitflow 或分支工作流的团队,SF 可以在 milestone 完成时自动创建 pull request:
|
||
|
||
```yaml
|
||
git:
|
||
auto_push: true
|
||
auto_pr: true
|
||
pr_target_branch: develop
|
||
```
|
||
|
||
这样会把 milestone 分支推送到远程,并创建一个目标分支为 `develop`(或你指定的其它分支)的 PR。要求已安装并认证 `gh` CLI。详见 [git.auto_pr](./configuration.md#gitauto_pr)。
|
||
|
||
### `commit_docs: false`
|
||
|
||
当设置为 `false` 时,SF 会把 `.sf/` 添加到 `.gitignore`,所有规划产物只保留在本地。适合只有部分成员使用 SF 的团队,或者公司要求仓库保持干净的场景。
|
||
|
||
## 自愈能力
|
||
|
||
SF 内置了对常见 git 问题的自动恢复:
|
||
|
||
- **Detached HEAD**:自动重新附着到正确分支
|
||
- **过期锁文件**:移除崩溃进程残留的 `index.lock`
|
||
- **孤儿 worktree**:检测并提供清理废弃 worktree 的选项(仅 worktree 模式)
|
||
|
||
可通过 `/sf doctor` 手动检查 git 健康状态。
|
||
|
||
## 原生 Git 操作
|
||
|
||
从 v2.16 起,SF 在派发热路径中的读密集 git 操作改用 libgit2 原生绑定。这消除了每次派发周期中约 70 次进程拉起,从而提升了自动模式吞吐量。
|