仓库管理方案:保持双仓库 + 跨仓库引用统一工单编号 #13

Closed
opened 2026-10-26 09:17:29 +00:00 by laoyang · 2 comments
Owner

现象 / 诉求

FamilyBook 与 FamilyBook Harmony 目前是两个独立仓库。每提一个需求,要在两个仓库各建一张工单、
提交时还要分别带各自的编号,流程负担重。希望评估:Gitea 是否有「子模块 / 子系统」这类方式,
把多个终端和主代码放在一个版本仓库里统一管理。

调研结论(已在本实例实测)

  • Gitea 1.27.3 的层级只有「仓库 → 工单/PR」,不存在子系统层。
  • Projects 看板只有 Web UI,没有 REST API:/api/v1/orgs/{org}/projects、
    /api/v1/user/projects、/api/v1/repos/{owner}/{repo}/projects、/api/v1/projects
    四个候选端点全部 404;实例 swagger 中 project 路径 0 条;
    社区 issue go-gitea/gitea#35921(2025-11-11)仍为未实现的 feature request。
    ⇒ 看板无法脚本化,不适合作为自动化提单流程的一环。
  • git submodule 不适用:两仓库无代码级依赖(PHP 服务端 ↔ ArkTS 客户端,仅 HTTP API 通信),
    submodule 用于引用外部依赖;采用后一次跨端需求由 2 个 commit 变 3 个。
  • monorepo 隐患 4 项:同名文件撞车 3 个(.gitignore / LICENSE / README.md);
    鸿蒙 .gitignore 中 16 条 / 根锚定规则搬迁后全部失效(/sign/、*.p12 私钥将从"已忽略"
    变为"可提交",属安全问题);两套构建入口需共处一工作区;_tooling 中 4 处硬编码路径
    (familybook_push.sh:52/1597/1622、familybook_harmonyos_run.sh:18)需改,且本机未装
    git filter-repo(搬迁历史会重写 163 个 commit 的 SHA)。
  • 可行的替代:跨仓库引用 owner/repo#N(Gitea 官方文档「自动链接引用」章节明确支持)。

决策(本次需求拍板)

  1. 保持双仓库,不做 monorepo、不引入 submodule。
  2. 工单主场 = 服务端仓库 laoyang/FamilyBook。跨端需求只在主场建一张单;
    纯端上需求可建在 harmonyos。
  3. 另一端(harmonyos)的 commit 写 laoyang/FamilyBook#N,由 Gitea 自动在主场工单生成反链,
    两端改动挂在同一张单下。
  4. 用 scoped label terminal/web、terminal/harmony 标注涉及哪一端,便于筛选。
  5. 以上规则写入长期记忆,后续所有需求自动照做。

验收标准

  • 实测确认 owner/repo#N 在本实例能生成 cross-reference 反链(不能只看文档)。
  • 两仓库均建立 terminal/web、terminal/harmony 两个 scoped label。
  • _tooling/_gitea.py 增加跨仓库引用辅助(提交信息里生成正确的引用串)。
  • 长期记忆(用户级 MEMORY.md)与工单流程说明更新到位。
  • 跨端工单示例:鸿蒙侧使用 laoyang/FamilyBook#N 引用后,主场工单可见反链。
## 现象 / 诉求 FamilyBook 与 FamilyBook Harmony 目前是两个独立仓库。每提一个需求,要在两个仓库各建一张工单、 提交时还要分别带各自的编号,流程负担重。希望评估:Gitea 是否有「子模块 / 子系统」这类方式, 把多个终端和主代码放在一个版本仓库里统一管理。 ## 调研结论(已在本实例实测) - Gitea 1.27.3 的层级只有「仓库 → 工单/PR」,**不存在子系统层**。 - **Projects 看板只有 Web UI,没有 REST API**:`/api/v1/orgs/{org}/projects`、 `/api/v1/user/projects`、`/api/v1/repos/{owner}/{repo}/projects`、`/api/v1/projects` 四个候选端点全部 404;实例 swagger 中 `project` 路径 0 条; 社区 issue go-gitea/gitea#35921(2025-11-11)仍为未实现的 feature request。 ⇒ 看板无法脚本化,不适合作为自动化提单流程的一环。 - **git submodule 不适用**:两仓库无代码级依赖(PHP 服务端 ↔ ArkTS 客户端,仅 HTTP API 通信), submodule 用于引用外部依赖;采用后一次跨端需求由 2 个 commit 变 3 个。 - **monorepo 隐患 4 项**:同名文件撞车 3 个(.gitignore / LICENSE / README.md); 鸿蒙 .gitignore 中 16 条 `/` 根锚定规则搬迁后全部失效(`/sign/`、`*.p12` 私钥将从"已忽略" 变为"可提交",属安全问题);两套构建入口需共处一工作区;`_tooling` 中 4 处硬编码路径 (familybook_push.sh:52/1597/1622、familybook_harmonyos_run.sh:18)需改,且本机未装 git filter-repo(搬迁历史会重写 163 个 commit 的 SHA)。 - **可行的替代:跨仓库引用 `owner/repo#N`**(Gitea 官方文档「自动链接引用」章节明确支持)。 ## 决策(本次需求拍板) 1. **保持双仓库**,不做 monorepo、不引入 submodule。 2. **工单主场 = 服务端仓库 laoyang/FamilyBook**。跨端需求只在主场建一张单; 纯端上需求可建在 harmonyos。 3. 另一端(harmonyos)的 commit 写 `laoyang/FamilyBook#N`,由 Gitea 自动在主场工单生成反链, 两端改动挂在同一张单下。 4. 用 scoped label `terminal/web`、`terminal/harmony` 标注涉及哪一端,便于筛选。 5. 以上规则写入长期记忆,后续所有需求自动照做。 ## 验收标准 - [ ] 实测确认 `owner/repo#N` 在本实例能生成 cross-reference 反链(不能只看文档)。 - [ ] 两仓库均建立 `terminal/web`、`terminal/harmony` 两个 scoped label。 - [ ] `_tooling/_gitea.py` 增加跨仓库引用辅助(提交信息里生成正确的引用串)。 - [ ] 长期记忆(用户级 MEMORY.md)与工单流程说明更新到位。 - [ ] 跨端工单示例:鸿蒙侧使用 `laoyang/FamilyBook#N` 引用后,主场工单可见反链。
Author
Owner

实测结果:跨仓库引用可用,但有三个坑

用对照实验(同一条评论内四个样本)在工单 #13 里跑过,结论如下。

✅ 语法本身有效

owner/repo#N 能正常渲染成 class="ref-issue" 的链接,#N 本仓库短引用也正常:

样本 渲染结果
laoyang/FamilyBook#4 ✅ 链接到 /laoyang/familybook/issues/4
laoyang/FamilyBook_harmonyos#1 ✅ 链接到 /laoyang/familybook_harmonyos/issues/1
#13 ✅ 链接到本工单
FamilyBook_harmonyos#1(省略 owner) ❌ 纯文本,省略 owner 不认

⚠️ 注意 href 里是 小写 familybook_harmonyos,而仓库真实名是 FamilyBook_harmonyos。
Gitea 对路径大小写不敏感,能正常跳转,但别依赖大小写精确匹配。

✅ 反链事件真的会生成

引用发出后,目标工单 FamilyBook_harmonyos#1 的时间线里出现了 2 条 comment_ref 事件
(从 3 条变 5 条)。⇒ 两端改动可以挂在同一张单下,方案成立。

🔴 坑一:引用后面紧跟中文全角括号,引用失效

写法 结果
...harmonyos#1 后面是空格 ✅ 渲染成链接
...harmonyos#1(紧跟全角括号) ❌ 纯文本,不渲染

这是本方案最容易踩的坑:中文写作习惯里 #1(说明) 极其常见,一旦这样写,
链接和反链双双失效,且没有任何报错。我第一版评论就是这么写的,实测才发现。

⇒ 规则:引用后面必须跟空格或行尾,绝不能直接接全角标点((、,、。、;)。

⚠️ 坑二:commit message 里的形式还要单独验证

上面验的是评论/正文渲染。commit message 走的是另一条解析路径(commit_ref),
owner/repo#N 在 commit 里能否同样触发跨仓库反链,尚未实测。
这需要在真实提交时验证一次——首次按新规则提交跨端改动时确认。

⚠️ 坑三:结论受 token scope 影响

本实例 token 只有 write:issue,write:repository,没有 read:user / read:organization
(/api/v1/user/orgs 返回 403)。本方案不依赖组织级功能,所以不受影响;
但如果将来想用组织级 Projects,得先补 scope。

结论

技术上可行,可以按「保持双仓库 + 跨仓库引用」执行。落地时要遵守一条硬规则:
引用 owner/repo#N 之后必须是空格或换行。

## 实测结果:跨仓库引用可用,但有三个坑 用对照实验(同一条评论内四个样本)在工单 #13 里跑过,结论如下。 ### ✅ 语法本身有效 `owner/repo#N` 能正常渲染成 `class="ref-issue"` 的链接,`#N` 本仓库短引用也正常: | 样本 | 渲染结果 | |---|---| | `laoyang/FamilyBook#4` | ✅ 链接到 `/laoyang/familybook/issues/4` | | `laoyang/FamilyBook_harmonyos#1` | ✅ 链接到 `/laoyang/familybook_harmonyos/issues/1` | | `#13` | ✅ 链接到本工单 | | `FamilyBook_harmonyos#1`(省略 owner) | ❌ 纯文本,**省略 owner 不认** | ⚠️ 注意 href 里是 **小写** `familybook_harmonyos`,而仓库真实名是 `FamilyBook_harmonyos`。 Gitea 对路径大小写不敏感,能正常跳转,但**别依赖大小写精确匹配**。 ### ✅ 反链事件真的会生成 引用发出后,目标工单 `FamilyBook_harmonyos#1` 的时间线里出现了 2 条 `comment_ref` 事件 (从 3 条变 5 条)。⇒ **两端改动可以挂在同一张单下**,方案成立。 ### 🔴 坑一:引用后面紧跟中文全角括号,引用失效 | 写法 | 结果 | |---|---| | `...harmonyos#1 后面是空格` | ✅ 渲染成链接 | | `...harmonyos#1(紧跟全角括号)` | ❌ 纯文本,不渲染 | **这是本方案最容易踩的坑**:中文写作习惯里 `#1(说明)` 极其常见,一旦这样写, 链接和反链**双双失效,且没有任何报错**。我第一版评论就是这么写的,实测才发现。 ⇒ 规则:**引用后面必须跟空格或行尾**,绝不能直接接全角标点(`(`、`,`、`。`、`;`)。 ### ⚠️ 坑二:commit message 里的形式还要单独验证 上面验的是**评论/正文**渲染。commit message 走的是另一条解析路径(`commit_ref`), `owner/repo#N` 在 commit 里能否同样触发跨仓库反链,尚未实测。 这需要在真实提交时验证一次——首次按新规则提交跨端改动时确认。 ### ⚠️ 坑三:结论受 token scope 影响 本实例 token 只有 `write:issue,write:repository`,没有 `read:user` / `read:organization` (`/api/v1/user/orgs` 返回 403)。本方案不依赖组织级功能,所以不受影响; 但如果将来想用组织级 Projects,得先补 scope。 ## 结论 技术上可行,可以按「保持双仓库 + 跨仓库引用」执行。落地时要遵守一条硬规则: **引用 `owner/repo#N` 之后必须是空格或换行**。
Author
Owner

收尾:方案已定并落地

用户三项决策:保持双仓库 + 跨仓库引用、工单主场 = laoyang/FamilyBook、规则写入长期记忆。
否决了 monorepo 与 git submodule(理由见正文;monorepo 的真风险是安全性的,不是体量的)。

已完成

  1. 实测确认跨仓库引用可用 —— owner/repo#N 渲染为 ref-issue 链接,
    目标工单时间线新增 comment_ref 反链事件(事件数 3 → 5)。
    同时查出三条坑:紧跟全角标点静默失效、不能省 owner、href 输出小写。
  2. 标签就位 —— 两仓库各建 terminal/web、terminal/harmony(exclusive=false,
    两者可同时挂,因为跨端需求本就该同时标)。
  3. 工具支持 —— gi.py 新增 ref 子命令 + 配置项 home_repo(已写入
    ~/.workbuddy/secrets/gitea.json,原文件已备份)。在客户端仓库里它会自动输出
    laoyang/FamilyBook#N,避免手敲成 #N 指错单。
    两个场景实地验证:
    • 在 FamilyBook 里 → #13
    • 在 FamilyBook_harmonyos 里 → laoyang/FamilyBook#13
  4. 回归验证 —— load_config 返回值由 4 元组改 5 元组,单点调用已同步;
    whoami / list / context 均正常。
  5. 规则固化 —— 用户级 MEMORY.md 第 3 步改写(不是追加,避免两套说法并存),
    并新增「多终端项目的仓库与工单组织」整节;skill gitea-issue-flow 的 SKILL.md
    第 3 步与命令速查同步更新。

遗留(不影响本方案成立)

  • commit message 里的跨仓库引用尚未实测:上文验证的是评论/正文渲染路径,
    commit 走 commit_ref 解析路径,需在首次真实跨端提交时确认一次。
  • 旧工具 _tooling/_gitea.py 已加弃用抬头(实际在用的是 gi.py),避免以后改错文件。

对既有工单的影响

现有 4 张单不符合新规则(分散在 2 个仓库),但都已关闭或无跨端内容,
不追溯迁移,从下一个需求开始按新规则执行。

## 收尾:方案已定并落地 用户三项决策:**保持双仓库 + 跨仓库引用**、**工单主场 = laoyang/FamilyBook**、**规则写入长期记忆**。 否决了 monorepo 与 git submodule(理由见正文;monorepo 的真风险是安全性的,不是体量的)。 ### 已完成 1. **实测确认跨仓库引用可用** —— `owner/repo#N` 渲染为 `ref-issue` 链接, 目标工单时间线新增 `comment_ref` 反链事件(事件数 3 → 5)。 同时查出三条坑:紧跟全角标点静默失效、不能省 owner、href 输出小写。 2. **标签就位** —— 两仓库各建 `terminal/web`、`terminal/harmony`(`exclusive=false`, 两者可同时挂,因为跨端需求本就该同时标)。 3. **工具支持** —— `gi.py` 新增 `ref` 子命令 + 配置项 `home_repo`(已写入 `~/.workbuddy/secrets/gitea.json`,原文件已备份)。在客户端仓库里它会自动输出 `laoyang/FamilyBook#N`,避免手敲成 `#N` 指错单。 两个场景实地验证: - 在 `FamilyBook` 里 → `#13` - 在 `FamilyBook_harmonyos` 里 → `laoyang/FamilyBook#13` 4. **回归验证** —— `load_config` 返回值由 4 元组改 5 元组,单点调用已同步; `whoami` / `list` / `context` 均正常。 5. **规则固化** —— 用户级 MEMORY.md 第 3 步改写(不是追加,避免两套说法并存), 并新增「多终端项目的仓库与工单组织」整节;skill `gitea-issue-flow` 的 SKILL.md 第 3 步与命令速查同步更新。 ### 遗留(不影响本方案成立) - **commit message 里的跨仓库引用尚未实测**:上文验证的是评论/正文渲染路径, commit 走 `commit_ref` 解析路径,需在首次真实跨端提交时确认一次。 - 旧工具 `_tooling/_gitea.py` 已加弃用抬头(实际在用的是 `gi.py`),避免以后改错文件。 ### 对既有工单的影响 现有 4 张单不符合新规则(分散在 2 个仓库),但都已关闭或无跨端内容, **不追溯迁移**,从下一个需求开始按新规则执行。
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: laoyang/FamilyBook#13