Skip to content

Commit ffe0da1

Browse files
committed
feat(sync-worktree): 实现 git worktree 同步技能的基础文档
- 创建技能文档 SKILL.md,包含完整的指令说明和实现步骤 - 更新任务清单,标记所有开发任务为已完成状态 - 实现状态概览、单分支同步、批量同步和冲突处理功能
1 parent ce7eaf7 commit ffe0da1

2 files changed

Lines changed: 285 additions & 22 deletions

File tree

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
---
2+
name: sync-worktree
3+
description: 在多个 git worktree 分支之间同步代码(rebase)。支持状态概览、单分支同步、批量同步、自定义基准分支。
4+
license: MIT
5+
metadata:
6+
author: mudssky
7+
version: "1.0"
8+
---
9+
10+
在多个 git worktree 分支之间通过 rebase 同步代码。
11+
12+
**输入**: `/sync-worktree` 后的参数决定运行模式:
13+
14+
| 用法 | 说明 |
15+
|------|------|
16+
| `/sync-worktree` | 状态概览:显示所有 worktree 的同步状态 |
17+
| `/sync-worktree <branch>` | 单分支同步:将指定分支 rebase 到 master |
18+
| `/sync-worktree <branch> --from <base>` | 自定义基准:将指定分支 rebase 到 `<base>` |
19+
| `/sync-worktree --all` | 批量同步:将所有 feature worktree rebase 到 master |
20+
21+
---
22+
23+
## Step 1: 发现 Worktree
24+
25+
执行以下命令发现所有 worktree:
26+
27+
```bash
28+
git worktree list --porcelain
29+
```
30+
31+
解析输出,构建 worktree 列表。每个 worktree 条目包含:
32+
- `worktree <path>` — 文件系统路径
33+
- `HEAD <sha>` — 当前 commit
34+
- `branch refs/heads/<name>` — 分支名
35+
36+
列表中的**第一个** worktree 是**主 worktree**。提取其分支名作为**默认基准分支**(通常是 `master``main`)。
37+
38+
将所有 worktree 存储为列表:`{ path, branch, head }`
39+
40+
---
41+
42+
## Step 2: 解析参数
43+
44+
从用户输入(ARGUMENTS 字符串)中判断模式:
45+
46+
1. **无参数** → 状态概览模式(跳转 Step 3)
47+
2. **`--all`** → 批量同步模式(跳转 Step 6)
48+
3. **`<branch>`** → 单分支同步模式
49+
- 检查是否同时提供了 `--from <base>`;如果有,使用该分支替代默认基准
50+
- 跳转 Step 4
51+
52+
---
53+
54+
## Step 3: 状态概览(无参数)
55+
56+
对每个 worktree 收集以下信息:
57+
58+
1. **相对于基准分支的领先/落后数**:对每个 feature worktree 执行:
59+
```bash
60+
git rev-list --left-right --count <base>...<branch>
61+
```
62+
输出格式:`<ahead>\t<behind>`(left = 基准领先数,right = 分支领先数)。
63+
- "ahead" = 该分支独有的 commit 数(基准没有的)
64+
- "behind" = 基准独有的 commit 数(需要同步的)
65+
66+
2. **工作区状态**:对每个 worktree 执行:
67+
```bash
68+
git -C <worktree-path> status --porcelain
69+
```
70+
输出为空 = clean;非空 = dirty。
71+
72+
以表格形式展示:
73+
74+
```
75+
┌─ Worktree Status ───────────────────────────────────────────────┐
76+
│ │
77+
│ Branch Path vs <base> │
78+
│ ────── ──── ───────── │
79+
│ master ✦ /path/to/main (base) │
80+
│ aifeat /path/to/aifeat-worktree ↑1 ↓2 ✔ │
81+
│ hotfix /path/to/hotfix-worktree ↑0 ↓3 ⚠ dirty│
82+
│ │
83+
│ ✦ = 当前所在 worktree │
84+
│ ↑ = 领先(自己独有的 commit) │
85+
│ ↓ = 落后(需要同步的 commit) │
86+
│ ✔ = clean ⚠ = dirty │
87+
└─────────────────────────────────────────────────────────────────┘
88+
```
89+
90+
如果没有 feature worktree(只有主 worktree),显示:
91+
> 当前没有可同步的 feature worktree。使用 `git worktree add` 创建新的 worktree。
92+
93+
**状态概览模式到此结束。**
94+
95+
---
96+
97+
## Step 4: 单分支同步
98+
99+
### 4.1 验证目标分支
100+
101+
检查指定的分支名是否存在于 worktree 列表中。如果不存在,报错并列出所有可用的 worktree 分支供用户选择。
102+
103+
如果指定了 `--from <base>`,验证该基准分支在本地是否存在:
104+
```bash
105+
git rev-parse --verify <base>
106+
```
107+
如果不存在,报错提示。
108+
109+
### 4.2 检查工作区状态
110+
111+
```bash
112+
git -C <worktree-path> status --porcelain
113+
```
114+
115+
如果输出**非空****拒绝**同步:
116+
> `<branch>` 工作区有未提交改动,请先 commit 或 stash 后重试。
117+
118+
**不得继续执行。** 不要提供自动 stash 的选项。
119+
120+
### 4.3 检查是否已是最新
121+
122+
检查基准分支是否有该分支没有的 commit:
123+
```bash
124+
git rev-list --count <branch>..<base>
125+
```
126+
127+
如果计数为 **0**,说明该分支已包含基准的所有 commit:
128+
> `<branch>` 已是最新,无需同步。
129+
130+
**到此结束。**
131+
132+
### 4.4 同步预览
133+
134+
展示将要应用的 commit:
135+
```bash
136+
git log --oneline <branch>..<base>
137+
```
138+
139+
显示格式:
140+
```
141+
将 rebase <branch> onto <base>
142+
143+
落后 <N> 个 commit:
144+
<sha1> <message1>
145+
<sha2> <message2>
146+
...
147+
```
148+
149+
### 4.5 执行 Rebase
150+
151+
```bash
152+
git -C <worktree-path> rebase <base>
153+
```
154+
155+
**如果 rebase 成功** → 跳转 Step 5(成功报告)
156+
157+
**如果 rebase 失败(冲突)** → 跳转 Step 4.6(冲突处理)
158+
159+
### 4.6 冲突处理(单分支模式)
160+
161+
当 rebase 产生冲突时:
162+
163+
1. 列出冲突文件:
164+
```bash
165+
git -C <worktree-path> diff --name-only --diff-filter=U
166+
```
167+
168+
2. 使用 **AskUserQuestion** 向用户提供三个选项:
169+
170+
| 选项 | 说明 |
171+
|------|------|
172+
| Claude 协助解决 | 读取冲突文件,分析冲突内容,提出解决方案 |
173+
| 手动解决后继续 | 用户自行解决冲突,之后告知 Claude 执行 `git -C <path> rebase --continue` |
174+
| 中止 rebase | 执行 `git -C <path> rebase --abort`,恢复到同步前状态 |
175+
176+
**如果用户选择「Claude 协助解决」**
177+
- 读取每个冲突文件
178+
- 分析冲突标记(`<<<<<<<``=======``>>>>>>>`
179+
- 提出解决方案并应用编辑
180+
- 暂存已解决的文件:`git -C <path> add <file>`
181+
- 继续 rebase:`git -C <path> rebase --continue`
182+
- 如果出现更多冲突,重复以上流程
183+
184+
---
185+
186+
## Step 5: 成功报告(单分支模式)
187+
188+
rebase 成功后,获取信息并展示:
189+
190+
```bash
191+
# 获取新 HEAD
192+
git -C <worktree-path> rev-parse --short HEAD
193+
```
194+
195+
```bash
196+
# 检查是否存在远程跟踪分支,判断是否需要 force push
197+
git -C <worktree-path> rev-parse --abbrev-ref --symbolic-full-name @{upstream} 2>/dev/null
198+
```
199+
200+
报告格式:
201+
```
202+
✔ <branch> 已同步到 <base>
203+
204+
新 HEAD: <short-sha> <message>
205+
同步 commit: <N> 个
206+
远程分支: <upstream>(需要 force push)| 无远程跟踪分支
207+
```
208+
209+
如果该分支有远程跟踪分支,提醒:
210+
> ⚠ 该分支有远程跟踪分支,rebase 后需要 `git push --force-with-lease` 来更新远程。
211+
212+
---
213+
214+
## Step 6: 批量同步(`--all`
215+
216+
### 6.1 枚举同步目标
217+
218+
从 worktree 列表(Step 1)中选取所有**非主 worktree**,作为同步目标。
219+
220+
如果没有 feature worktree:
221+
> 当前没有可同步的 feature worktree。
222+
223+
### 6.2 逐个处理分支
224+
225+
对每个 feature worktree 执行单分支同步流程(Step 4.1–4.5),但有以下区别:
226+
227+
- **脏工作区** → 记录为 `⚠ 跳过(脏工作区)`,继续处理下一个分支
228+
- **已是最新** → 记录为 `ℹ 已是最新`,继续处理下一个分支
229+
- **rebase 冲突** → 执行 `git -C <path> rebase --abort`,记录为 `❌ 跳过(冲突)`,继续处理下一个分支
230+
- **成功** → 记录为 `✔ 成功`,继续处理下一个分支
231+
232+
**不要因任何单个分支的失败而停止。** 始终处理所有分支。
233+
234+
### 6.3 汇总报告
235+
236+
所有分支处理完毕后,显示汇总表格:
237+
238+
```
239+
┌─ Sync Summary ──────────────────────────────────────────────┐
240+
│ │
241+
│ Branch Status Detail │
242+
│ ────── ────── ────── │
243+
│ aifeat ✔ 成功 同步了 3 个 commit │
244+
│ hotfix ⚠ 跳过 脏工作区 │
245+
│ experiment ❌ 跳过 rebase 冲突 │
246+
│ docs ℹ 已是最新 — │
247+
│ │
248+
│ 结果: 1 成功 / 1 跳过(脏) / 1 跳过(冲突) / 1 已是最新 │
249+
└─────────────────────────────────────────────────────────────┘
250+
```
251+
252+
如果有因冲突被跳过的分支,补充提示:
253+
> ⚠ 冲突分支可单独处理:`/sync-worktree <branch>` 后手动解决冲突。
254+
255+
---
256+
257+
## 安全护栏
258+
259+
- **禁止自动 stash**:工作区有未提交改动时,直接拒绝并告知用户先 commit 或 stash。
260+
- **禁止执行 `git push`**:本 skill 仅做本地 rebase。如需 force push,只提醒用户,不代为执行。
261+
- **禁止使用 `git rebase -i`**:交互式 rebase 需要终端输入,不受支持。
262+
- **批量模式冲突必须 abort**`--all` 模式下遇到冲突时,始终执行 `git rebase --abort` 并跳过。
263+
- **始终验证分支存在性**:在执行任何操作前,确认目标分支存在于 worktree 列表中。
Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,39 @@
11
## 1. Skill 基础结构
22

3-
- [ ] 1.1 创建 `.claude/skills/sync-worktree/SKILL.md` 文件,包含 frontmatter(name、description、metadata)和完整的 skill 指令
4-
- [ ] 1.2 编写参数解析逻辑说明:无参数(状态概览)、`<branch>`(单分支同步)、`--from <branch>`(自定义基准)、`--all`(批量同步)
3+
- [x] 1.1 创建 `.claude/skills/sync-worktree/SKILL.md` 文件,包含 frontmatter(name、description、metadata)和完整的 skill 指令
4+
- [x] 1.2 编写参数解析逻辑说明:无参数(状态概览)、`<branch>`(单分支同步)、`--from <branch>`(自定义基准)、`--all`(批量同步)
55

66
## 2. 状态概览功能
77

8-
- [ ] 2.1 实现 worktree 发现:调用 `git worktree list --porcelain` 解析所有 worktree 的分支和路径
9-
- [ ] 2.2 实现基准分支检测:从主 worktree(bare=false 的第一个)提取分支名作为默认基准
10-
- [ ] 2.3 实现领先/落后计算:对每个 feature worktree 调用 `git rev-list --left-right --count <base>...<branch>`
11-
- [ ] 2.4 实现工作区状态检查:对每个 worktree 调用 `git -C <path> status --porcelain` 判断 clean/dirty
12-
- [ ] 2.5 实现状态表格输出格式:分支名、路径、ahead、behind、工作区状态,主 worktree 标记为 base
8+
- [x] 2.1 实现 worktree 发现:调用 `git worktree list --porcelain` 解析所有 worktree 的分支和路径
9+
- [x] 2.2 实现基准分支检测:从主 worktree(bare=false 的第一个)提取分支名作为默认基准
10+
- [x] 2.3 实现领先/落后计算:对每个 feature worktree 调用 `git rev-list --left-right --count <base>...<branch>`
11+
- [x] 2.4 实现工作区状态检查:对每个 worktree 调用 `git -C <path> status --porcelain` 判断 clean/dirty
12+
- [x] 2.5 实现状态表格输出格式:分支名、路径、ahead、behind、工作区状态,主 worktree 标记为 base
1313

1414
## 3. 单分支同步功能
1515

16-
- [ ] 3.1 实现目标分支验证:检查指定分支名是否存在于 worktree 列表中,不存在则列出可用分支
17-
- [ ] 3.2 实现脏工作区拒绝:检查目标 worktree 工作区状态,脏则拒绝并提示 commit 或 stash
18-
- [ ] 3.3 实现已是最新检测:通过 `git rev-list --count <base>..<branch>` 和反向检查判断是否需要同步
19-
- [ ] 3.4 实现同步预览:显示将要同步的 commit 列表(`git log --oneline <merge-base>..<base>`
20-
- [ ] 3.5 实现 rebase 执行:`git -C <worktree-path> rebase <base-branch>`
21-
- [ ] 3.6 实现成功报告:显示新 HEAD、同步的 commit 数、是否需要 force push
16+
- [x] 3.1 实现目标分支验证:检查指定分支名是否存在于 worktree 列表中,不存在则列出可用分支
17+
- [x] 3.2 实现脏工作区拒绝:检查目标 worktree 工作区状态,脏则拒绝并提示 commit 或 stash
18+
- [x] 3.3 实现已是最新检测:通过 `git rev-list --count <base>..<branch>` 和反向检查判断是否需要同步
19+
- [x] 3.4 实现同步预览:显示将要同步的 commit 列表(`git log --oneline <merge-base>..<base>`
20+
- [x] 3.5 实现 rebase 执行:`git -C <worktree-path> rebase <base-branch>`
21+
- [x] 3.6 实现成功报告:显示新 HEAD、同步的 commit 数、是否需要 force push
2222

2323
## 4. 冲突处理
2424

25-
- [ ] 4.1 实现单分支冲突检测:识别 rebase 失败的退出码和冲突文件列表
26-
- [ ] 4.2 实现三选项交互:(1) Claude 协助解决 (2) 用户手动解决后 continue (3) abort
27-
- [ ] 4.3 实现批量模式冲突跳过:检测到冲突后自动 `git -C <path> rebase --abort`,记录跳过原因
25+
- [x] 4.1 实现单分支冲突检测:识别 rebase 失败的退出码和冲突文件列表
26+
- [x] 4.2 实现三选项交互:(1) Claude 协助解决 (2) 用户手动解决后 continue (3) abort
27+
- [x] 4.3 实现批量模式冲突跳过:检测到冲突后自动 `git -C <path> rebase --abort`,记录跳过原因
2828

2929
## 5. 批量同步功能
3030

31-
- [ ] 5.1 实现 `--all` 模式:遍历所有非主 worktree,逐个执行同步流程
32-
- [ ] 5.2 实现跳过逻辑:脏工作区 → 跳过;冲突 → abort + 跳过;已是最新 → 标记
33-
- [ ] 5.3 实现汇总报告:表格显示每个分支的最终状态(✔ 成功 / ⚠ 跳过-脏工作区 / ❌ 跳过-冲突 / ℹ 已是最新)
31+
- [x] 5.1 实现 `--all` 模式:遍历所有非主 worktree,逐个执行同步流程
32+
- [x] 5.2 实现跳过逻辑:脏工作区 → 跳过;冲突 → abort + 跳过;已是最新 → 标记
33+
- [x] 5.3 实现汇总报告:表格显示每个分支的最终状态(✔ 成功 / ⚠ 跳过-脏工作区 / ❌ 跳过-冲突 / ℹ 已是最新)
3434

3535
## 6. 验证
3636

37-
- [ ] 6.1 在当前 worktree 环境下测试 `/sync-worktree`(无参数)状态概览输出
38-
- [ ] 6.2 测试 `/sync-worktree aifeat` 单分支同步流程
39-
- [ ] 6.3 验证脏工作区拒绝行为
37+
- [x] 6.1 在当前 worktree 环境下测试 `/sync-worktree`(无参数)状态概览输出
38+
- [x] 6.2 测试 `/sync-worktree aifeat` 单分支同步流程
39+
- [x] 6.3 验证脏工作区拒绝行为

0 commit comments

Comments
 (0)