@ohos-cpf/3rdloop 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -87
- package/lib/cli.js +25 -0
- package/lib/config-cmd.js +1 -1
- package/lib/serve.js +268 -0
- package/lib/update.js +46 -6
- package/lib/web-ext.js +454 -0
- package/lib/web.js +664 -0
- package/package.json +2 -1
- package/vendor/Server/Agent/SkillSelector/README.md +11 -11
- package/vendor/Server/Agent/SkillSelector/llm/llmClient.js +3 -3
- package/vendor/Server/Skills/arkts-code-use/SKILL.md +270 -0
- package/vendor/Server/Skills/arkts-code-use/assets/TEMPLATES.md +367 -0
- package/vendor/Server/Skills/arkts-code-use/references/API_VERIFICATION.md +144 -0
- package/vendor/Server/Skills/arkts-code-use/references/ARKTS_RULES.md +240 -0
- package/vendor/Server/Skills/arkts-code-use/references/CODE_PATTERNS.md +431 -0
- package/vendor/Server/Skills/arkts-code-use/references/SYNTAX_CHECK_GUIDE.md +164 -0
- package/vendor/Server/Skills/arkts-code-use/scripts/verify-arkts.cjs +428 -0
- package/vendor/Server/Skills/gitcode-repo-fork/SKILL.md +310 -0
- package/vendor/Server/Skills/gitcode-repo-fork/assets/FORK_REPORT_TEMPLATE.md +113 -0
- package/vendor/Server/Skills/gitcode-repo-fork/references/FORK_DECISION_GUIDE.md +124 -0
- package/vendor/Server/Skills/gitcode-repo-fork/references/GITCODE_FORK_API.md +95 -0
- package/vendor/Server/Skills/gitcode-repo-fork/scripts/gitcode-fork.cjs +285 -0
- package/vendor/VERSION +3 -3
- package/web/css/arktslibrarycheck.css +322 -0
- package/web/css/codecheck.css +464 -0
- package/web/css/flutterlibrarycheck.css +322 -0
- package/web/css/knowledge.css +332 -0
- package/web/css/loop.css +578 -0
- package/web/css/md-reader.css +240 -0
- package/web/css/rnlibrarycheck.css +322 -0
- package/web/css/theme.css +702 -0
- package/web/index.html +713 -0
- package/web/js/arktslibrarycheck.js +1413 -0
- package/web/js/codecheck.js +1039 -0
- package/web/js/flutterlibrarycheck.js +1364 -0
- package/web/js/health.js +69 -0
- package/web/js/knowledge.js +358 -0
- package/web/js/loop.js +1102 -0
- package/web/js/md-reader.js +435 -0
- package/web/js/navigation.js +238 -0
- package/web/js/rnlibrarycheck.js +1378 -0
- package/web/js/stats.js +110 -0
- package/web/js/theme.js +46 -0
- package/web/js/utils.js +228 -0
- package/web/knowledge.html +146 -0
- package/web/loop.html +219 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gitcode-repo-fork
|
|
3
|
+
description: 'GitCode 仓库 Fork 准备工具。当需要修改的 GitCode 仓库不属于 Token 用户(无推送权限)时,自动将源仓库 Fork 到 Token 用户名下:幂等复用已有 Fork、创建后轮询就绪、克隆或接入本地工作区并配置 origin(fork)+upstream(源仓库) 双 remote 与提交人身份、落后分支 fast-forward 同步(禁强推),产出 fork-info.json 与报告,供后续代码修改与 ohos-lib-pr-push 提 PR 流程复用。USE FOR: 任何"需要修改非本人 GitCode 仓库"的流程前置阶段(Fork + 工作区准备)。'
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
compatibility: 需要 Node.js 18+(执行 scripts/gitcode-fork.cjs),需要 git 命令行,需要 GitCode API Token(默认读取 3rdLibraryLoop/Server/.env 的 GIT_TOKEN)
|
|
6
|
+
metadata:
|
|
7
|
+
author: LoopEngine
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
category: gitcode-repo
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# GitCode Repo Fork — 非本人仓库 Fork 准备
|
|
13
|
+
|
|
14
|
+
将**不属于 Token 用户**的 GitCode 仓库 Fork 到 Token 用户名下,并准备好可直接修改、可直接推送的本地工作区(origin=fork / upstream=源仓库),打通"修改 → 推送 → 提 PR"链路的前置环节。
|
|
15
|
+
|
|
16
|
+
> ⚠️ **核心原则:① 只 Fork 不改码——本 SKILL 只做"权限判定 → Fork → 工作区准备 → 同步检查",不修改任何业务代码;② 幂等——已有 Fork 复用、已有工作区接入、已同步不重复操作;③ 禁破坏——禁删除重建 Fork、禁 force push,Fork 分叉时只报告不自动处理;④ Token 绝不写入报告、日志与 fork-info.json(remote URL 展示时必须脱敏)。**
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 任务参数
|
|
21
|
+
|
|
22
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
23
|
+
|------|------|------|------|
|
|
24
|
+
| `repoUrl` | string | ✅ | 目标(源)仓库 GitCode 地址,支持 `/tree/{branch}`(含 `/-/tree/`)与 `?branch=` 内嵌分支;`/tree/{branch}/{subpath}` 视为 monorepo 子路径(仅记录,不单独克隆) |
|
|
25
|
+
| `workspaceDir` | string | ✅ | 本地工作区绝对路径。**已存在且为指向源仓库或其 Fork 的 git 克隆** → 走"已有工作区接入"(Phase 4.1);**不存在或为空目录** → 克隆 Fork 到该路径(Phase 4.2);非空且非 git 仓库 → 终止 |
|
|
26
|
+
| `branch` | string | ❌ | 工作分支。优先级:本参数 > repoUrl 内嵌分支 > 源仓库 `default_branch` |
|
|
27
|
+
| `token` | string | ❌ | GitCode Token。不提供时读取 `3rdLibraryLoop/Server/.env` 的 `GIT_TOKEN`(见 Phase 1.2) |
|
|
28
|
+
| `forkOwner` | string | ❌ | Fork 目标 namespace(Token 用户登录名)。默认由 `get-user` 自动获取;**Token 无 `read_user` scope(get-user 返回 403)时必须提供**(见 Phase 1.3) |
|
|
29
|
+
| `syncMode` | string | ❌ | `auto`(默认):复用 Fork 且目标分支落后、无分叉时 fast-forward 同步;`none`:只检查不同步,结果记入报告 |
|
|
30
|
+
| `plainRemote` | boolean | ❌ | 默认 `false`:origin(fork)remote URL 内嵌 Token,使后续 `git push` 免交互(Token 仅存于本地 `.git/config`)。`true` 时不嵌入,依赖系统 credential helper |
|
|
31
|
+
| `dryRun` | boolean | ❌ | 默认 `false`。`true` 时只做只读探测(权限/Fork 状态/分支存在性/工作区布局预判),不执行 Fork/克隆/remote 变更/同步,不写任何文件,结果以文本汇报 |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 输入依赖
|
|
36
|
+
|
|
37
|
+
- **前置 SKILL**: 无(通常是代码修改类任务的第一个环节)
|
|
38
|
+
- **输入文件**: 无(通过 `repoUrl` 定位源仓库)
|
|
39
|
+
- **下游消费者**: 代码修改类 SKILL(如 `rnoh-lib-code-adapt`、`rn-lib-add-example` 等);`ohos-lib-pr-push`(其工作区约定 origin=fork / upstream=源仓库,本 SKILL 的 remote 布局与其完全对齐,fork 的 `parent` 字段亦满足其 Phase 1.1 上游推断)
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 工作流程概览
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Phase 1: 解析输入与 Token(repoUrl → owner/repo/branch;Token → Token 用户身份)
|
|
47
|
+
↓
|
|
48
|
+
Phase 2: 权限与必要性判定(有推送权限 → 无需 Fork,终止报告;
|
|
49
|
+
分支确定与存在性探测)
|
|
50
|
+
↓
|
|
51
|
+
Phase 3: Fork 幂等检测与创建(已有且 parent 正确 → 复用;
|
|
52
|
+
命名冲突 → 终止;否则创建并轮询就绪)
|
|
53
|
+
↓
|
|
54
|
+
Phase 4: 本地工作区准备(克隆 Fork,或已有工作区 remote 手术接入;
|
|
55
|
+
origin=fork / upstream=源仓库;仓库级提交人身份)
|
|
56
|
+
↓
|
|
57
|
+
Phase 5: 分支同步检查(仅复用 Fork 时;落后无分叉 → ff 同步;
|
|
58
|
+
分叉 → 只报告禁强推)
|
|
59
|
+
↓
|
|
60
|
+
Phase 6: 验证与产出(fork-info.json + gitcode-repo-fork-report.md)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
> 各判定分支的完整决策树参见 [Fork 决策指南](references/FORK_DECISION_GUIDE.md);API 细节与踩坑记录参见 [GitCode Fork API 参考](references/GITCODE_FORK_API.md)
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Phase 1:解析输入与 Token
|
|
68
|
+
|
|
69
|
+
### 1.1 解析 repoUrl
|
|
70
|
+
|
|
71
|
+
从 `repoUrl` 解析 `upstreamOwner` / `repoName` / `branch` / `monorepoSubpath`:
|
|
72
|
+
|
|
73
|
+
| URL 形式 | 解析结果 |
|
|
74
|
+
|----------|---------|
|
|
75
|
+
| `https://gitcode.com/{owner}/{repo}` | branch=null(后续取默认分支) |
|
|
76
|
+
| `https://gitcode.com/{owner}/{repo}.git` | 去掉 `.git` 后缀 |
|
|
77
|
+
| `https://gitcode.com/{owner}/{repo}/tree/{branch}` | branch={branch} |
|
|
78
|
+
| `https://gitcode.com/{owner}/{repo}/-/tree/{branch}` | GitLab 风格路径,等价上一行 |
|
|
79
|
+
| `https://gitcode.com/{owner}/{repo}/tree/{branch}/{subpath}` | branch + monorepoSubpath(仅记录到 fork-info,克隆整个仓库) |
|
|
80
|
+
| `https://gitcode.com/{owner}/{repo}?branch={branch}` | branch={branch} |
|
|
81
|
+
|
|
82
|
+
- 域名必须是 `gitcode.com`(允许 `www.` 前缀);其他域名(gitee/github 等)→ **终止并报告**"本 SKILL 仅处理 GitCode 仓库"
|
|
83
|
+
- `monorepoSubpath` 非空时在报告与 fork-info 中标注(后续 PR 场景需注明子库位置,与 ohos-lib-pr-push 的 Monorepo 处理一致)
|
|
84
|
+
|
|
85
|
+
### 1.2 确定 Token
|
|
86
|
+
|
|
87
|
+
按优先级取值:
|
|
88
|
+
|
|
89
|
+
1. 用户显式传入的 `token` 参数
|
|
90
|
+
2. 读取 `3rdLibraryLoop/Server/.env` 中的 `GIT_TOKEN`(从本 SKILL 目录向上回溯:`SKILL 目录 = Server/Skills/gitcode-repo-fork`,`.env` 位于 `../../../.env`)
|
|
91
|
+
3. 都没有 → **终止并提示用户提供 Token**
|
|
92
|
+
|
|
93
|
+
### 1.3 获取 Token 用户身份
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
node scripts/gitcode-fork.cjs get-user --token "$GIT_TOKEN"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
记录返回的 `username`(登录名,**Fork 目标 namespace**)、`name`、`email`。
|
|
100
|
+
|
|
101
|
+
**Token 无 `read_user` scope 的兜底**(实测存在:返回 `403 no scopes:read_user`):
|
|
102
|
+
|
|
103
|
+
- 改用用户传入的 `forkOwner` 参数作为 Fork 目标 namespace;`name`/`email` 缺失时提交人配置改用 `{forkOwner}` 与 `{forkOwner}@noreply.gitcode.com`(在报告中注明"Token 缺 read_user scope,提交人邮箱为占位值")
|
|
104
|
+
- `forkOwner` 也未提供 → **终止并提示**:"Token 无 read_user scope,请传 forkOwner 参数,或为 Token 增加该 scope"
|
|
105
|
+
|
|
106
|
+
> 派生变量:`tokenUser` = get-user 的 `username` 或 `forkOwner` 参数。
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Phase 2:权限与必要性判定
|
|
111
|
+
|
|
112
|
+
### 2.1 获取源仓库信息
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
node scripts/gitcode-fork.cjs get-repo --token "$GIT_TOKEN" --owner {upstreamOwner} --repo {repoName}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
记录:`id`(project_id)、`defaultBranch`、`parent`(源仓库本身是 fork 时的更上游,仅记录)、`permissions`(`{pull, push, admin}`,可能为 null)。
|
|
119
|
+
|
|
120
|
+
### 2.2 判定是否需要 Fork
|
|
121
|
+
|
|
122
|
+
| 判定依据 | 结果 |
|
|
123
|
+
|---------|------|
|
|
124
|
+
| `permissions.push == true` | **无需 Fork**:Token 用户对源仓库有写权限 → 终止并报告"可直接克隆修改,如需隔离开发建议建分支而非 Fork(平台通常拒绝 Fork 自己的仓库)"。用户明确指示仍要 Fork 时按指示继续,由 Phase 3 的 API 错误处理兜底 |
|
|
125
|
+
| `upstreamOwner == Token 用户 username` | 同上(owner 比对兜底) |
|
|
126
|
+
| `permissions` 为 null 且 owner 不同 | 按无写权限处理,**报告中标注"permissions 字段缺失,按 owner 比对判定"** |
|
|
127
|
+
| 无写权限 | 继续 Phase 3 |
|
|
128
|
+
|
|
129
|
+
### 2.3 确定并探测工作分支
|
|
130
|
+
|
|
131
|
+
1. `branch` = 用户参数 > repoUrl 内嵌分支 > 源仓库 `defaultBranch`
|
|
132
|
+
2. 探测源仓库分支存在性:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
node scripts/gitcode-fork.cjs get-branch --token "$GIT_TOKEN" --owner {upstreamOwner} --repo {repoName} --branch {branch}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
3. 返回 `exists: false` → **终止并报告**"分支 {branch} 在源仓库不存在"
|
|
139
|
+
|
|
140
|
+
> `dryRun=true` 时:完成 Phase 1~3.1 后跳过一切写操作,将探测结果(权限判定、Fork 存在性、分支存在性、工作区模式预判)以文本汇报,**不执行 Fork/克隆/remote 变更/同步,不写任何文件**
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Phase 3:Fork 幂等检测与创建
|
|
145
|
+
|
|
146
|
+
### 3.1 探测已有 Fork
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
node scripts/gitcode-fork.cjs get-repo --token "$GIT_TOKEN" --owner {tokenUser} --repo {repoName} --allow-missing
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
| 探测结果 | 处置 |
|
|
153
|
+
|---------|------|
|
|
154
|
+
| `exists: false` | 走 3.2 创建 |
|
|
155
|
+
| `exists: true` 且 `parent` 为 `{upstreamOwner}/{repoName}` | **复用**(记录 `reused: true`),跳到 3.4 |
|
|
156
|
+
| `exists: true` 且 `parent` 为空或指向其他仓库 | **命名冲突**:Token 用户名下已有同名但非本仓库 Fork 的仓库 → **终止并报告**,提示用户先处理该仓库(重命名/删除),**禁止误用或覆盖** |
|
|
157
|
+
|
|
158
|
+
### 3.2 创建 Fork
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
node scripts/gitcode-fork.cjs create-fork --token "$GIT_TOKEN" --owner {upstreamOwner} --repo {repoName} --timeout 60
|
|
162
|
+
# Token 无 read_user scope 时(Phase 1.3 兜底路径)显式指定 Fork 目标:
|
|
163
|
+
node scripts/gitcode-fork.cjs create-fork --token "$GIT_TOKEN" --owner {upstreamOwner} --repo {repoName} --fork-owner {tokenUser} --timeout 60
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
- Fork 创建到 **Token 用户名下**,仓库名默认与源仓库一致
|
|
167
|
+
- 脚本内置幂等回查:POST 失败时自动回查 `{tokenUser}/{repoName}`,已存在则返回 `reused: true`(仍需按 3.1 校验 `parent`)
|
|
168
|
+
- 返回 `reused: true` 而探测 3.1 为不存在(并发创建等罕见场景)→ 按 3.1 规则校验后复用
|
|
169
|
+
- 其他失败 → **终止并报告**原始错误
|
|
170
|
+
|
|
171
|
+
### 3.3 等待 Fork 就绪
|
|
172
|
+
|
|
173
|
+
`create-fork` 已内置就绪轮询(Fork 为异步操作,刚创建的仓库 API 可能短暂 404)。若单独轮询:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
node scripts/gitcode-fork.cjs wait-fork --token "$GIT_TOKEN" --owner {tokenUser} --repo {repoName} --timeout 60 --interval 3
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
超时未就绪 → **终止并报告**"Fork 可能仍在后台创建,请稍后重跑(已有 Fork 会被 3.1 幂等复用)"。
|
|
180
|
+
|
|
181
|
+
### 3.4 校验 Fork 分支
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
node scripts/gitcode-fork.cjs get-branch --token "$GIT_TOKEN" --owner {tokenUser} --repo {repoName} --branch {branch}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Fork 复制源仓库全部分支,一般必存在;`exists: false`(极端:Fork 期间源分支被删)→ **终止并报告**。
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Phase 4:本地工作区准备
|
|
192
|
+
|
|
193
|
+
> 先探测 `workspaceDir` 状态选择路径:存在 `.git` → 4.1 接入;不存在或为空目录 → 4.2 克隆;非空且非 git 仓库 → **终止并报告**。
|
|
194
|
+
|
|
195
|
+
### 4.1 已有工作区接入(remote 手术,不动工作区内容)
|
|
196
|
+
|
|
197
|
+
适用于"已从源仓库克隆并可能已有修改,才发现无推送权限"的场景(**工作区有未提交修改属预期输入,remote 手术不影响工作区**):
|
|
198
|
+
|
|
199
|
+
1. 校验 git 仓库:`git rev-parse --show-toplevel`;记录当前分支 `git branch --show-current`、`git remote -v`、工作区状态 `git status --porcelain`
|
|
200
|
+
2. **remote 手术**(目标布局:origin=fork、upstream=源仓库):
|
|
201
|
+
|
|
202
|
+
| 现状 | 操作 |
|
|
203
|
+
|------|------|
|
|
204
|
+
| origin 指向源仓库,无 upstream remote | `git remote rename origin upstream` + `git remote add origin {forkCloneUrl}` |
|
|
205
|
+
| origin 指向源仓库,upstream 已存在 | `git remote set-url origin {forkCloneUrl}`(upstream 保持) |
|
|
206
|
+
| origin 已指向 fork(owner == Token 用户) | 仅补 upstream:缺则 `git remote add upstream {upstreamUrl}`;已存在则校验指向,不符时 `git remote set-url upstream {upstreamUrl}` 并在报告注明覆盖 |
|
|
207
|
+
| origin 指向无关仓库 | **终止并报告**,交由用户确认 |
|
|
208
|
+
|
|
209
|
+
3. 统一收尾:`git remote set-url origin {forkCloneUrl}`(幂等,确保 Token 嵌入;`plainRemote=true` 时用不含 Token 的 `{forkUrl}`)
|
|
210
|
+
4. **分支对齐**(目标:当前分支 = `{branch}`):
|
|
211
|
+
|
|
212
|
+
| 现状 | 处置 |
|
|
213
|
+
|------|------|
|
|
214
|
+
| 当前分支 == 目标分支 | 无操作 |
|
|
215
|
+
| 不同且工作区干净 | `git fetch origin` 后 `git checkout {branch}`(本地无该分支时自动跟踪 `origin/{branch}`) |
|
|
216
|
+
| 不同且工作区有未提交修改 | **不切换**(防丢改动),报告警告"停留在当前分支 {current},请在提交修改后再切换到 {branch}" |
|
|
217
|
+
|
|
218
|
+
5. 设置仓库级提交人(Token 用户身份,避免本地全局配置冒名):
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
git config user.name "{name}"
|
|
222
|
+
git config user.email "{email}"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 4.2 新克隆 Fork
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
# 完整克隆(非 --depth=1:后续需要提交/推送/rebase 同步,浅克隆受限)
|
|
229
|
+
git clone -b {branch} {forkCloneUrl} {workspaceDir}
|
|
230
|
+
# 降级重试:去掉 -b,克隆默认分支后 git checkout {branch}
|
|
231
|
+
git remote add upstream {upstreamUrl}
|
|
232
|
+
git config user.name "{name}" && git config user.email "{email}"
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
- `{forkCloneUrl}`:`plainRemote=false` 时为 `https://{token}@gitcode.com/{tokenUser}/{repoName}.git`(Token 仅存于 `.git/config`);`true` 时为 `https://gitcode.com/{tokenUser}/{repoName}.git`
|
|
236
|
+
- 克隆时输出"警告:重定向到 .../xxx.git/"属 **GitCode 正常行为**(自动补全 `.git` 后缀重定向),**不算失败、不触发降级重试**;判定失败以**命令退出码非 0 或目标目录无仓库内容**为准
|
|
237
|
+
- 大仓库完整克隆耗时属预期
|
|
238
|
+
|
|
239
|
+
### 4.3 Monorepo 子路径
|
|
240
|
+
|
|
241
|
+
`monorepoSubpath` 非空时:克隆整个仓库(不使用 sparse-checkout),在报告与 fork-info 中记录子库路径,供后续修改与 PR 流程标注。
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Phase 5:分支同步检查(仅复用 Fork 时执行;新建 Fork 跳过——刚创建必与上游一致,记 `skipped-new-fork`)
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
git fetch upstream
|
|
249
|
+
git fetch origin
|
|
250
|
+
git rev-list --left-right --count upstream/{branch}...origin/{branch} # 输出 "上游独有<TAB>fork独有"
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
| 判定 | 输出特征 | 处置 |
|
|
254
|
+
|------|---------|------|
|
|
255
|
+
| 一致 | `0<TAB>0` | 记 `in-sync`,无操作 |
|
|
256
|
+
| Fork 领先 | `0<TAB>N` | 记 `fork-ahead`(用户此前的工作,**不动**) |
|
|
257
|
+
| Fork 落后、无分叉 | `N<TAB>0` | `syncMode=auto` → 同步(见下);`syncMode=none` → 记 `skipped-mode-none` |
|
|
258
|
+
| 分叉 | `N<TAB>M`(均 >0) | 记 `diverged`,**只报告禁强推**:提示"fork 的 {branch} 与上游分叉,请人工确认(可 rebase 后重推);本流程禁止 force push / 自动 rebase" |
|
|
259
|
+
|
|
260
|
+
**落后同步操作**(全部 fast-forward 安全,任何非 ff 均被 git 拒绝,无需额外判断):
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# ① 远端同步:直接把 fork 远端分支快进到上游(不依赖本地检出状态)
|
|
264
|
+
git push origin upstream/{branch}:{branch}
|
|
265
|
+
# ② 本地跟进:仅当当前在目标分支且工作区干净时
|
|
266
|
+
git merge --ff-only upstream/{branch}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
- ① 失败(non-fast-forward)→ 说明期间有并发变更,按分叉处理(记 `diverged`,只报告)
|
|
270
|
+
- ② 跳过时(不在目标分支/工作区脏)→ 报告注明"本地工作区未跟进,请在合适时机 `git merge --ff-only upstream/{branch}`"
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Phase 6:验证与产出
|
|
275
|
+
|
|
276
|
+
### 6.1 验证
|
|
277
|
+
|
|
278
|
+
| 检查项 | 命令 | 预期 |
|
|
279
|
+
|--------|------|------|
|
|
280
|
+
| remote 布局 | `git remote -v` | origin → fork(`{tokenUser}/{repoName}`)、upstream → 源仓库(**展示输出前将 Token 替换为 `***` 脱敏**) |
|
|
281
|
+
| 当前分支 | `git branch --show-current` | == `{branch}`(4.1 脏工作区保留原分支的除外,报告注明) |
|
|
282
|
+
| 提交人 | `git config user.name` / `user.email` | Token 用户身份 |
|
|
283
|
+
| HEAD | `git rev-parse HEAD` | 记录到 fork-info |
|
|
284
|
+
|
|
285
|
+
### 6.2 产出文件(仅以下两个,均写入 `{workspaceDir}`;dryRun 不写)
|
|
286
|
+
|
|
287
|
+
- **`{workspaceDir}/fork-info.json`** — 机器可读元信息(上游/fork/分支/remote 布局/同步状态/commit,**不含 Token**),供下游 SKILL 与 ohos-lib-pr-push 复用
|
|
288
|
+
- **`{workspaceDir}/gitcode-repo-fork-report.md`** — 人类可读报告
|
|
289
|
+
|
|
290
|
+
两个文件的模板见 [Fork 报告模板](assets/FORK_REPORT_TEMPLATE.md)。
|
|
291
|
+
|
|
292
|
+
报告必须包含"后续步骤"指引:① 在 `{workspaceDir}` 的 `{branch}` 分支上完成代码修改(调用相应修改类 SKILL);② 修改完成后执行 `ohos-lib-pr-push`(其 origin=fork / upstream=源仓库 布局已由本 SKILL 就位)。
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## 注意事项
|
|
297
|
+
|
|
298
|
+
- **只准备不修改**:发现代码问题应停下报告,不顺手改代码;本 SKILL 的产出仅为 Fork + 工作区 + 元信息
|
|
299
|
+
- **幂等**:Fork 已存在(parent 正确)→ 复用;工作区已接入 → 只做 remote 校正;已同步 → 不重复操作。重跑安全(各 Phase 均先探测后执行)
|
|
300
|
+
- **禁破坏**:禁删除重建 Fork(无法可靠验证"无在用分支",删除可能毁掉用户已有工作);禁 force push / 自动 pull / rebase(同步只做 ff-only,分叉只报告)
|
|
301
|
+
- **Token 安全**:Token 可出现在 clone/remote URL(本地 `.git/config`,属正常用法),但**绝不写入报告、fork-info.json、日志正文**;任何 `git remote -v` 输出展示前必须脱敏
|
|
302
|
+
- **判定兜底**:API 未返回 `permissions` 时按 owner 比对判定并在报告标注;拿不准时**终止询问用户**,禁止默认带写权限处理
|
|
303
|
+
- **Fork of Fork**:目标仓库本身是 fork 时,仍 Fork 该仓库本身(fork 的 `parent` = 该仓库,其更上游仅记录);后续 PR 提交目标即该仓库
|
|
304
|
+
- **工作区保护**:已有工作区有未提交修改属预期(remote 手术不影响);但分支切换、本地 ff 跟进在脏工作区下跳过并警告,防丢改动
|
|
305
|
+
- **顺序不可颠倒**:权限判定(Phase 2)→ Fork(Phase 3)→ 工作区(Phase 4)→ 同步(Phase 5)→ 产出(Phase 6);先 Fork 后克隆(克隆的是 fork,不是源仓库)
|
|
306
|
+
- **失败恢复**:任一步失败保留已完成信息写入报告后终止;重跑时 Phase 3.1 幂等检测会复用已创建的 Fork,Phase 4 remote 手术幂等收敛到目标布局
|
|
307
|
+
|
|
308
|
+
## 流程步骤顺序速查
|
|
309
|
+
|
|
310
|
+
1. 解析 repoUrl(gitcode.com 域名校验 → owner/repo/branch/monorepoSubpath)→ 2. 确定 Token(参数 > `Server/.env` 的 `GIT_TOKEN`)→ 3. `get-user` 获取 Token 用户(fork 目标 namespace;**403 无 read_user scope 时用 `forkOwner` 参数兜底**,email 以 noreply 占位并注明)→ 4. `get-repo` 源仓库(id/default_branch/parent/permissions)→ 5. **权限判定(push=true 或 owner=Token 用户 → 无需 Fork 终止;permissions 缺失按 owner 比对并标注)** → 6. 确定分支(参数 > URL 内嵌 > default_branch)+ `get-branch` 探测存在性 → 7. **`get-repo --allow-missing` 探测已有 Fork(parent 正确 → 复用;命名冲突 → 终止)** → 8. 不存在 → `create-fork`(内置幂等回查 + 就绪轮询,异步 404 属正常)→ 9. `get-branch` 校验 fork 分支 → 10. **工作区准备**(已有 git 克隆 → remote 手术:origin=fork/upstream=源仓库 + 脏工作区不切分支;否则完整克隆 fork + add upstream;统一设置仓库级提交人)→ 11. **同步检查(仅复用 Fork)**:`rev-list --left-right` 四态(一致/fork 领先不动/落后 → `git push origin upstream/{b}:{b}` ff 同步 + 本地 `merge --ff-only` 跟进/分叉 → 只报告禁强推)→ 12. 验证(remote 布局脱敏展示/分支/提交人/HEAD)→ 13. 产出 `fork-info.json` + `gitcode-repo-fork-report.md`(含后续步骤:修改类 SKILL → `ohos-lib-pr-push`)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Fork 报告模板(gitcode-repo-fork)
|
|
2
|
+
|
|
3
|
+
> Phase 6 产出两个文件:`fork-info.json`(机器可读,供下游 SKILL)与 `gitcode-repo-fork-report.md`(人类可读)。均写入 `{workspaceDir}`。**任何字段不得包含 Token。**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## fork-info.json 模板
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"upstream": {
|
|
12
|
+
"owner": "{upstreamOwner}",
|
|
13
|
+
"repo": "{repoName}",
|
|
14
|
+
"url": "https://gitcode.com/{upstreamOwner}/{repoName}",
|
|
15
|
+
"projectId": "{源仓库 id}",
|
|
16
|
+
"defaultBranch": "{default_branch}",
|
|
17
|
+
"grandparent": "{源仓库自身的 parent,非 fork 时为 null}"
|
|
18
|
+
},
|
|
19
|
+
"fork": {
|
|
20
|
+
"owner": "{tokenUser}",
|
|
21
|
+
"repo": "{repoName}",
|
|
22
|
+
"url": "https://gitcode.com/{tokenUser}/{repoName}",
|
|
23
|
+
"reused": true,
|
|
24
|
+
"createdAt": "{本次流程时间}"
|
|
25
|
+
},
|
|
26
|
+
"tokenUser": "{username}",
|
|
27
|
+
"branch": "{branch}",
|
|
28
|
+
"monorepoSubpath": "{子库路径或 null}",
|
|
29
|
+
"workspaceDir": "{workspaceDir}",
|
|
30
|
+
"remotes": {
|
|
31
|
+
"origin": "fork",
|
|
32
|
+
"upstream": "源仓库"
|
|
33
|
+
},
|
|
34
|
+
"workspaceMode": "clone | attach",
|
|
35
|
+
"commit": "{git rev-parse HEAD}",
|
|
36
|
+
"sync": {
|
|
37
|
+
"status": "in-sync | fork-ahead | synced-ff | skipped-mode-none | diverged | skipped-new-fork",
|
|
38
|
+
"detail": "{同步明细,如 '落后 3 个提交已 ff 同步' / '分叉:上游独有 2,fork 独有 1,未自动处理'}"
|
|
39
|
+
},
|
|
40
|
+
"branchAlignment": "{attached-kept-current(脏工作区保留原分支 {current})| aligned | cloned}",
|
|
41
|
+
"time": "{timestamp}"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## gitcode-repo-fork-report.md 模板
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
# GitCode 仓库 Fork 报告
|
|
51
|
+
|
|
52
|
+
## 基本信息
|
|
53
|
+
|
|
54
|
+
| 项 | 值 |
|
|
55
|
+
|----|----|
|
|
56
|
+
| 执行时间 | {timestamp} |
|
|
57
|
+
| 模式 | 新建 Fork / 复用 Fork |
|
|
58
|
+
| 工作区模式 | 新克隆 / 已有工作区接入 |
|
|
59
|
+
| dry-run | 否 |
|
|
60
|
+
|
|
61
|
+
## 判定明细
|
|
62
|
+
|
|
63
|
+
| 判定项 | 结果 | 依据 |
|
|
64
|
+
|--------|------|------|
|
|
65
|
+
| 是否需要 Fork | 需要 / 不需要(终止) | permissions.push={true/false}(或 owner 比对兜底,标注"permissions 缺失") |
|
|
66
|
+
| Fork 存在性 | 不存在→已创建 / 已存在→复用 / 命名冲突→终止 | parent={值} |
|
|
67
|
+
| 分支 | {branch}(来源:参数/URL/默认分支) | 上游分支存在:是 |
|
|
68
|
+
|
|
69
|
+
## 仓库信息
|
|
70
|
+
|
|
71
|
+
| 项 | 源仓库(上游) | Fork |
|
|
72
|
+
|----|---------------|------|
|
|
73
|
+
| 路径 | {upstreamOwner}/{repoName} | {tokenUser}/{repoName} |
|
|
74
|
+
| 地址 | https://gitcode.com/{upstreamOwner}/{repoName} | https://gitcode.com/{tokenUser}/{repoName} |
|
|
75
|
+
| 默认分支 | {defaultBranch} | — |
|
|
76
|
+
| project_id | {id} | — |
|
|
77
|
+
|
|
78
|
+
## 工作区
|
|
79
|
+
|
|
80
|
+
| 项 | 值 |
|
|
81
|
+
|----|----|
|
|
82
|
+
| 路径 | {workspaceDir} |
|
|
83
|
+
| remote 布局 | origin → fork({tokenUser}/{repoName});upstream → 源仓库 |
|
|
84
|
+
| 当前分支 | {branch}(或"保留原分支 {current}:工作区有未提交修改,未切换") |
|
|
85
|
+
| 提交人 | {name} <{email}>(Token 用户,仓库级配置) |
|
|
86
|
+
| HEAD | {commit} |
|
|
87
|
+
| Monorepo 子路径 | {subpath 或"无"} |
|
|
88
|
+
|
|
89
|
+
## 分支同步状态
|
|
90
|
+
|
|
91
|
+
| 状态 | 说明 |
|
|
92
|
+
|------|------|
|
|
93
|
+
| {sync.status} | {sync.detail} |
|
|
94
|
+
|
|
95
|
+
## 后续步骤
|
|
96
|
+
|
|
97
|
+
1. 在 `{workspaceDir}` 的 `{branch}` 分支上完成代码修改(调用相应修改类 SKILL)
|
|
98
|
+
2. 修改完成后执行 `ohos-lib-pr-push` 从 fork 向源仓库提 PR(工作区布局已满足其输入前提)
|
|
99
|
+
3. {如有分叉/命名冲突等待处理事项,逐条列出处理建议}
|
|
100
|
+
|
|
101
|
+
## 错误信息
|
|
102
|
+
|
|
103
|
+
{无 / 错误详情与已完成的产物清单}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 填写规则
|
|
109
|
+
|
|
110
|
+
- **Token 安全**:`fork.url` / remote 地址一律使用不含 Token 的形式;remote URL 内嵌 Token 仅存在于本地 `.git/config`
|
|
111
|
+
- **状态枚举**:`sync.status` 只取模板中列出的枚举值,自定义状态写入 `detail`
|
|
112
|
+
- **终止场景**:流程中途终止时报告仍需生成(写入可写的位置),已完成步骤的产物信息(如已创建的 Fork 地址)必须保留
|
|
113
|
+
- **dryRun**:不写任何文件,结果以流程输出文本呈现(可参照本模板组织内容)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Fork 决策指南(gitcode-repo-fork)
|
|
2
|
+
|
|
3
|
+
本 SKILL 的四个核心判定分支的完整决策树、场景矩阵与安全红线。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 决策树 1:是否需要 Fork(Phase 2)
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
获取源仓库信息(get-repo)
|
|
11
|
+
├── permissions.push == true ──────────────→ 无需 Fork:终止报告
|
|
12
|
+
│ (可直接克隆修改;如需隔离开发建议建分支,
|
|
13
|
+
│ 平台通常拒绝 Fork 自己的仓库)
|
|
14
|
+
├── permissions 缺失
|
|
15
|
+
│ ├── upstreamOwner == Token 用户 ───────→ 无需 Fork:终止报告
|
|
16
|
+
│ └── 不同 ─────────────────────────────→ 按无写权限处理,报告标注"按 owner 比对判定"
|
|
17
|
+
└── permissions.push == false ─────────────→ 需要 Fork:继续 Phase 3
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
> 用户明确指示"仍要 Fork"时按指示继续(用户指令优先),由 Phase 3 的 API 错误处理兜底;判定拿不准时终止询问用户,禁止默认带写权限。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 决策树 2:Fork 三态(Phase 3)
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
探测 {tokenUser}/{repoName}(get-repo --allow-missing)
|
|
28
|
+
├── exists: false ─────────────────────────→ 创建(create-fork,内置幂等回查+就绪轮询)
|
|
29
|
+
├── exists: true
|
|
30
|
+
│ ├── parent == {upstreamOwner}/{repoName} → 复用(reused: true)
|
|
31
|
+
│ └── parent 为空 / 指向其他仓库 ─────────→ 命名冲突:终止报告,
|
|
32
|
+
│ 提示用户先处理同名仓库(重命名/删除),
|
|
33
|
+
│ 禁止误用或覆盖
|
|
34
|
+
└── create-fork 返回 reused: true(并发创建)→ 按本树校验 parent 后复用
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**为什么禁止删除重建 Fork**:API 删除不可恢复,且无法可靠验证对方仓库"无在用分支/未推送提交";落后场景 ff 同步可达同等效果,分叉场景属用户已有工作,必须人工决策。
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 决策树 3:工作区三态(Phase 4)
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
workspaceDir 状态探测
|
|
45
|
+
├── 存在 .git(git 仓库)
|
|
46
|
+
│ └── 已有工作区接入(Phase 4.1,remote 手术,不动工作区内容)
|
|
47
|
+
│ ├── origin 指向源仓库、无 upstream → rename origin→upstream + add origin=fork
|
|
48
|
+
│ ├── origin 指向源仓库、有 upstream → set-url origin=fork(upstream 保持)
|
|
49
|
+
│ ├── origin 已指向 fork(owner=Token 用户)→ 补/校正 upstream
|
|
50
|
+
│ └── origin 指向无关仓库 → 终止报告,交由用户确认
|
|
51
|
+
│ 分支对齐:当前==目标 → 无操作;不同且干净 → checkout;
|
|
52
|
+
│ 不同且脏(有未提交修改)→ 不切换,警告(防丢改动)
|
|
53
|
+
├── 不存在 / 空目录
|
|
54
|
+
│ └── 新克隆 Fork(Phase 4.2):完整克隆(非 --depth=1)+ add upstream + 仓库级提交人
|
|
55
|
+
└── 非空且非 git 仓库 ─────────────────────→ 终止报告
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**关键认知**:"已从源仓库克隆并已有修改,才发现无推送权限"是本 SKILL 的**主场景之一**——脏工作区属预期输入,remote 手术(rename/add/set-url)不触碰工作区内容,安全。
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 决策树 4:同步四态(Phase 5,仅复用 Fork 时)
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
git rev-list --left-right --count upstream/{b}...origin/{b}
|
|
66
|
+
输出 "上游独有<TAB>fork独有"
|
|
67
|
+
├── 0, 0 ────→ in-sync(无操作)
|
|
68
|
+
├── 0, N ────→ fork-ahead(用户此前的工作,不动)
|
|
69
|
+
├── N, 0 ────→ fork 落后、无分叉
|
|
70
|
+
│ ├── syncMode=auto → ① git push origin upstream/{b}:{b}(远端 ff,不依赖本地检出)
|
|
71
|
+
│ │ ② 当前在目标分支且干净 → git merge --ff-only upstream/{b} 本地跟进
|
|
72
|
+
│ │ (否则报告本地跟进指引)
|
|
73
|
+
│ └── syncMode=none → skipped-mode-none(报告记录)
|
|
74
|
+
└── N, M ────→ diverged:只报告禁强推,提示人工处理(可 rebase 后重推)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**安全机制**:`git push origin upstream/{b}:{b}` 不带 `--force` 时 git 天然拒绝非 fast-forward,无需自行判断;本地 `--ff-only` 同理。分叉绝不自动处理。
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 场景矩阵
|
|
82
|
+
|
|
83
|
+
| 场景 | 触发条件 | 行为 |
|
|
84
|
+
|------|---------|------|
|
|
85
|
+
| dry-run 探测 | `dryRun=true` | Phase 1~3.1 只读探测后文本汇报,不写文件、不执行任何变更 |
|
|
86
|
+
| 已有工作区接入 | workspaceDir 存在 `.git` | remote 手术 + 分支对齐(脏则跳过切换)+ 提交人 |
|
|
87
|
+
| 新克隆 | workspaceDir 不存在/空 | 完整克隆 fork + upstream remote + 提交人 |
|
|
88
|
+
| 复用已有 Fork | Phase 3.1 命中 | 不创建;Phase 5 必做同步检查 |
|
|
89
|
+
| 新建 Fork | Phase 3.1 未命中 | 创建 + 轮询就绪;Phase 5 跳过(记 `skipped-new-fork`) |
|
|
90
|
+
| Monorepo 子路径 | repoUrl 含 `/tree/{b}/{subpath}` | 克隆整个仓库,subpath 记入 fork-info 与报告(后续 PR 标注) |
|
|
91
|
+
| Fork of Fork | 源仓库响应含 `parent` | 仍 Fork 该仓库本身;更上游仅记录 |
|
|
92
|
+
| 命名冲突 | 同名仓库存在但 parent 不符 | 终止,交由用户处理 |
|
|
93
|
+
| 有写权限 | `permissions.push=true` | 无需 Fork,终止报告 |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 安全红线
|
|
98
|
+
|
|
99
|
+
1. **禁删除重建 Fork**——破坏性且无法可靠验证安全性(见决策树 2)
|
|
100
|
+
2. **禁 force push / 自动 pull / 自动 rebase**——同步只做 ff-only;分叉只报告
|
|
101
|
+
3. **Token 脱敏**——不入报告 / fork-info.json / 日志;`git remote -v` 展示前替换为 `***`
|
|
102
|
+
4. **脏工作区保护**——不切换分支、不本地 ff 跟进,只警告
|
|
103
|
+
5. **只准备不修改**——不改任何业务代码,产出仅 Fork + 工作区 + 两个元信息文件
|
|
104
|
+
6. **终止优于猜测**——判定拿不准(权限缺失、remote 指向不明、命名冲突)一律终止询问用户
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 上下游协作
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
任务规划
|
|
112
|
+
↓
|
|
113
|
+
gitcode-repo-fork(本 SKILL:非本人仓库 → Fork + 工作区准备)
|
|
114
|
+
↓
|
|
115
|
+
代码修改类 SKILL(rnoh-lib-code-adapt / rn-lib-add-example / arkts-library-demo-code 等)
|
|
116
|
+
↓
|
|
117
|
+
ohos-lib-pr-push(fork → 源仓库提 PR;其 origin=fork / upstream=源仓库 布局已就位)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
| 相邻 SKILL | 关系 |
|
|
121
|
+
|-----------|------|
|
|
122
|
+
| `arkts-library-source-clone` | **只读检视**用 source-clone(克隆源仓库到 `outputDir/source/`,无推送诉求);**需要修改并回推**用本 SKILL(克隆的是 fork,带推送能力) |
|
|
123
|
+
| `ohos-lib-pr-push` | 直接下游。其 Phase 1.1 上游推断(origin/upstream/parent)、Phase 5 推送(fork remote 内嵌 Token)均依赖本 SKILL 的工作区布局 |
|
|
124
|
+
| 各修改类 SKILL | 在本 SKILL 产出的 `{workspaceDir}`(分支 `{branch}`)上工作;fork-info.json 提供仓库元信息 |
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# GitCode Fork API 参考(gitcode-repo-fork)
|
|
2
|
+
|
|
3
|
+
所有 API 可通过 `node scripts/gitcode-fork.cjs <cmd> --help` 查看参数。
|
|
4
|
+
|
|
5
|
+
Base: `https://gitcode.com/api/v5`
|
|
6
|
+
|
|
7
|
+
认证方式:**所有请求统一使用 Header `Authorization: Bearer {token}`**(脚本已内置)。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## API 一览
|
|
12
|
+
|
|
13
|
+
| 操作 | 方法 | 端点 | 关键参数 / 返回 |
|
|
14
|
+
|------|------|------|----------------|
|
|
15
|
+
| 获取用户信息 | GET | `/user` | 返回 `login`(登录名 = Fork 目标 namespace)、`name`、`email` |
|
|
16
|
+
| 获取仓库信息 | GET | `/repos/{owner}/{repo}` | 返回 `id`(project_id)、`default_branch`、`parent.path_with_namespace`(fork 的直接源仓库)、`permissions`(`{pull,push,admin}`,可能缺失);脚本 `get-repo` 已封装,`--allow-missing` 时 404 → `{exists:false}` |
|
|
17
|
+
| 探测分支存在 | GET | `/repos/{owner}/{repo}/branches/{branch}` | 200 存在 / 404 不存在(脚本 `get-branch` 已封装) |
|
|
18
|
+
| 创建 Fork | POST | `/repos/{owner}/{repo}/forks` | `name`(可选,fork 仓库名,默认与源仓库同名);Fork 创建到 **Token 用户名下**;脚本 `create-fork` 已封装(幂等回查 + 就绪轮询) |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 踩坑记录
|
|
23
|
+
|
|
24
|
+
### 1. POST 写操作认证必须用 Bearer 头(2026-08 ohos_checksum 实战)
|
|
25
|
+
|
|
26
|
+
- ❌ POST 时把 token 放在 form body 的 `access_token` 字段会被拒:`401 token not found`
|
|
27
|
+
- ✅ POST 一律用 Header `Authorization: Bearer {token}`;GET 用 Bearer 头或 query 参数均可(本脚本统一 Bearer 头)
|
|
28
|
+
- 来源于 ohos-lib-pr-push 的 GITCODE_API.md 实战记录,本脚本实现已遵循
|
|
29
|
+
|
|
30
|
+
### 2. Fork 是异步操作,创建后可能短暂 404
|
|
31
|
+
|
|
32
|
+
- `POST /repos/{owner}/{repo}/forks` 返回成功 ≠ 仓库立即可访问;刚创建的 Fork 在数秒内可能 404
|
|
33
|
+
- ✅ 创建后必须**轮询** `GET /repos/{forkOwner}/{repo}` 直到 200(脚本 `wait-fork` / `create-fork` 内置,默认超时 60s、间隔 3s)
|
|
34
|
+
- 超时不代表失败:Fork 可能仍在后台创建,稍后重跑即可(幂等探测会复用)
|
|
35
|
+
|
|
36
|
+
### 3. Fork 已存在的处理(幂等策略)
|
|
37
|
+
|
|
38
|
+
- Fork API 在 fork 已存在时可能报错(409/400,错误文案不稳定,**不要依赖错误文案做分支判断**)
|
|
39
|
+
- ✅ 策略:**先 GET 探测后创建**(`GET /repos/{tokenUser}/{repo}`);创建失败时回查一次,仓库已出现则按"复用"返回
|
|
40
|
+
- 复用前必须校验 `parent` 是否等于目标源仓库 `{owner}/{repo}`:
|
|
41
|
+
- `parent` 正确 → 复用
|
|
42
|
+
- `parent` 为空或指向其他仓库 → **命名冲突**(Token 用户名下已有同名非本仓库 Fork 的仓库),终止交由用户处理,**禁止误用/覆盖**
|
|
43
|
+
- ⚠️ **禁止删除重建 Fork**(区别于旧文档"无未合并分支可删除重 Fork"的策略):无法可靠验证对方仓库"无在用分支",API 删除是破坏性操作且无法恢复;落后用 ff 同步即可达到同等效果,分叉场景属用户已有工作,必须人工决策
|
|
44
|
+
|
|
45
|
+
### 4. permissions 字段判定写权限
|
|
46
|
+
|
|
47
|
+
- 仓库响应的 `permissions` 对象(`{pull, push, admin}`)是"是否需要 Fork"的权威判据:`push == true` → 无需 Fork
|
|
48
|
+
- **实测(2026-09 CPF-RN 组织仓库):`permissions` 可能为 null** → 兜底:`owner == Token 用户 username` 比对;两者都无法判定时终止询问用户,**禁止默认带写权限处理**
|
|
49
|
+
|
|
50
|
+
### 4.5 Token 可能缺 read_user scope(2026-09 实测)
|
|
51
|
+
|
|
52
|
+
- `GET /user` 可能返回 `403 no scopes:read_user`——Token 创建时未勾选用户信息读取权限
|
|
53
|
+
- 影响:无法自动获取 Token 用户登录名(Fork 目标 namespace)
|
|
54
|
+
- ✅ 兜底:`create-fork` 支持 `--fork-owner` 显式指定(跳过 /user 查询);SKILL 层面提供 `forkOwner` 任务参数
|
|
55
|
+
- 提交人 `email` 不可得时用 `{forkOwner}@noreply.gitcode.com` 占位并在报告注明
|
|
56
|
+
- 长期建议:为 Token 补充 read_user scope
|
|
57
|
+
|
|
58
|
+
### 5. Fork of Fork 语义
|
|
59
|
+
|
|
60
|
+
- 目标仓库本身是 fork(响应含 `parent`)时,`POST forks` 仍 Fork **该仓库本身**(新 fork 的 `parent` = 该仓库,不追溯更上游)
|
|
61
|
+
- 后续 PR 的提交目标 = 被 Fork 的仓库(ohos-lib-pr-push 通过 fork 仓库的 `parent` 字段推断上游,与本语义一致)
|
|
62
|
+
|
|
63
|
+
### 6. GitCode clone 重定向警告属正常行为(KB: experiences/gitcode-clone-redirect-warning-normal)
|
|
64
|
+
|
|
65
|
+
- `git clone https://gitcode.com/xxx/yyy` 输出"警告:重定向到 .../yyy.git/"是 GitCode 自动补全 `.git` 后缀的正常行为
|
|
66
|
+
- **不算失败、不触发降级重试**;判定克隆失败以命令退出码非 0 或目标目录无仓库内容为准
|
|
67
|
+
|
|
68
|
+
### 7. Token 嵌入 remote URL 的惯例与红线
|
|
69
|
+
|
|
70
|
+
- `https://{token}@gitcode.com/{user}/{repo}.git` 形式的 clone/remote URL 可使后续 `git push` 免交互(ohos-lib-pr-push 的 Fork 模式同款用法)
|
|
71
|
+
- **为什么允许明文内嵌**(设计决策,经评审确认保持):① 下游 `ohos-lib-pr-push` 需无人值守推送,无 credential helper 的环境(Linux 常见)会卡死在交互式密码提示;② URL 内嵌是唯一零依赖、三平台行为一致的免交互方式;③ 信任边界不变——Token 本就以明文存于 `Server/.env`,`.git/config` 同为本机用户级文件,HTTPS 下只发给 gitcode.com
|
|
72
|
+
- 已知残余风险(接受):后续会话 `git remote -v` 可见明文;工作区打包/共享时 `.git/config` 随之暴露。更严格的替代方案(`git credential approve` 注入系统凭证管理器 + 干净 remote)已评估,因跨平台自动化可靠性优先而未采用;如未来环境变化(如统一 macOS)可重新评估
|
|
73
|
+
- Token 仅存于本地 `.git/config`,属可接受的正常用法
|
|
74
|
+
- **红线**:Token 绝不写入报告、fork-info.json、日志正文、issue/PR 内容;`git remote -v` 输出展示前必须将 Token 替换为 `***`
|
|
75
|
+
|
|
76
|
+
### 8. 提交人身份
|
|
77
|
+
|
|
78
|
+
- 不设置仓库级 `git config user.name/user.email` 时,提交人使用本地全局配置,可能与 Token 所属用户不一致(上游显示为"陌生人"提交)
|
|
79
|
+
- 克隆/Fork 后立即设置仓库级配置(本 SKILL Phase 4 已内置)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 与 ohos-lib-pr-push 的衔接契约
|
|
84
|
+
|
|
85
|
+
本 SKILL 产出的工作区直接满足 ohos-lib-pr-push 的输入前提:
|
|
86
|
+
|
|
87
|
+
| 契约项 | 本 SKILL 的落实 |
|
|
88
|
+
|--------|----------------|
|
|
89
|
+
| origin 指向 fork 仓库 | Phase 4 remote 手术 / 克隆自 fork |
|
|
90
|
+
| upstream(或可推断的)指向源仓库 | Phase 4 `git remote add upstream` |
|
|
91
|
+
| fork 仓库 API 的 `parent` 字段可推断上游 | Fork 创建后 parent 恒为源仓库 |
|
|
92
|
+
| 仓库级提交人 = Token 用户 | Phase 4.1 步骤 5 / Phase 4.2 |
|
|
93
|
+
| Token 可推送 | fork remote URL 内嵌 Token(`plainRemote=false` 默认) |
|
|
94
|
+
|
|
95
|
+
ohos-lib-pr-push Phase 5 推送失败提示"用 Token Fork 后添加 remote 再推"的场景,即本 SKILL Phase 4.1 的"已有工作区接入"路径——先跑本 SKILL 再重跑 pr-push 即可。
|