Repository navigation
[bug] teamai push 无法指定目标分支:Gitee 等泛型 host 上 CLI 不会自动建 PR,新资源会悬空在 teamai/push/* 分支上(过程中还有一次 hard reset) #663
Description
English summary —
teamai pushhas no way to target the default branch: it always creates
teamai/push/<user>/<timestamp>and relies on the provider's PR automation. There is no Gitee
provider in the bundle (Gitee appears only inside an unrelated GitCode comment), so Gitee falls
through to the generic provider and PR creation throws
Automatic pull/merge request creation is not supported for generic Git hosts.A push that
contained real new content — 2 new skills,906 insertions(+), no deletions — then sat unmerged on
a remote branch with no PR and no visible signal.push --helpaccepts only
--all / --skill / --role / --project: there is no option to push to the default branch.
Separately, areset --hard HEADruns during the push sequence (per reflog), which silently
discarded an uncommitted change in my working tree.Correction (2026-09-19) — an earlier revision of this issue claimed the pushed branch carried
destructive deletions (907 insertions(+), 4618 deletions(-), removingskills/team-wiki-codebase/*).
That claim was wrong and I have removed it. I compared withgit diff <default>..<branch>
against a branch that was already an ancestor of the default branch, which reverses the diff
direction and renders everything the default branch gained later as "deletions". The real proposal
isgit diff <default>...<branch>, which is empty for that branch. There is no destructive
deletion behaviour to report. Sorry for the noise.
Description
teamai push 的落点是写死的:永远新建一个 teamai/push/<user>/<timestamp> 分支,然后交给 provider 去开 PR/MR。命令本身没有任何指定目标分支的开关:
$ teamai push --help
Options:
--all Push all without confirmation
--skill <path> Push a specific skill by path
--role <id> Target role namespace for pushed project skills
--project <id> Target a project
而 provider 侧没有 Gitee 实现——在 bundle 里搜 gitee 只有一处命中,还是 GitCode 的注释:
// GitCode's API addresses repos by the plain `owner/repo` path (Gitee-style),
// not a URL-encoded id. Kept for interface parity with other providers.所以 Gitee 落到泛型 provider,PR 自动化直接抛错:
Automatic pull/merge request creation is not supported for generic Git hosts.
后果:有真实新内容的推送会静静悬空
第二次推送(teamai/push/C/20260919-190031)带着 2 个新 skill,相对默认分支的真实提议是:
$ git diff --stat master...teamai/push/C/20260919-190031
skills/jira-workflow-transition/SKILL.md | 607 ++++++++++++++++++++++
skills/neusoft-localization-delivery/CONTRIBUTORS | 1 +
skills/neusoft-localization-delivery/SKILL.md | 297 +++++++++++
4 files changed, 906 insertions(+)纯新增、零删除。但 CLI 报完那句错就结束了:
- 分支推上去了(
git ls-remote能看到),用户会以为 push 成功了; - 没有 PR(仓库 PR 列表里只有 sync: v0.16.3 from internal #1,且 sync: v0.16.3 from internal #1 属于更早的那次推送);
- 分支就一直挂在远端,直到我手工清理时才发现它从没被合并。
对比很说明问题:更早那次推送的 PR #1(head = teamai/push/C/20260919-173548)确实合并了——但那个 PR 是手工在 Gitee 上建的(17:38:38 创建、17:39:10 合并),不是 CLI 建的,因为 CLI 根本没有 Gitee provider。两次推送的差别不是配置,而是"人有没有去手动开 PR"。
换句话说:在 Gitee 上,teamai push 的自动化在"建分支"之后就断了,剩下那一步完全依赖用户自己发现、自己去网页上补。而 CLI 的输出里没有任何东西告诉你"需要你手动去开 PR"。
push 过程中还有一次 hard reset
pushRepoBranch() 里有 reset --hard + clean -fd 的路径:
await git.add(files);
const status = await git.status();
if (status.staged.length === 0) {
await git.reset(["--hard", "HEAD"]);
await git.clean("f", ["-d"]);
...
}实际后果(reflog 可查,本机 2026-09-19):
$ git reflog --date=format:'%H:%M:%S' | sed -n '5,9p'
592d5f9 HEAD@{19:00:24}: reset: moving to HEAD ← hard reset
592d5f9 HEAD@{19:00:32}: checkout: moving from master to teamai/push/C/20260919-190031
6819735 HEAD@{19:00:34}: commit: [teamai] Push 2 resource(s) from C
592d5f9 HEAD@{19:00:40}: checkout: moving from teamai/push/C/20260919-190031 to master我在 push 之前改好的 env/env.yaml 没有进那次提交——它被这次 hard reset 丢掉了,我事后只能重新改一遍再手动提交。整个过程里 push 没有任何提示说"你有未提交的改动会被丢弃"。附带地,push 后 git status 还出现过一批 D skills/...,需要用 git checkout -- . 恢复干净。
Reproduction
- 团队仓库远端指向 Gitee(或任何非 GitHub/TGit 的泛型 host)。
- 本地准备一份有新内容的推送目标(例如一个新 skill),
teamai push --all。 - 观察:
- 分支
teamai/push/<user>/<ts>出现在远端; - CLI 打印
Automatic pull/merge request creation is not supported for generic Git hosts.; - 没有 PR 被创建,变更不会进默认分支;CLI 也没有提示"请手动开 PR"。
- 分支
- 若此时工作区有未提交改动,对照 reflog 可见一次
reset: moving to HEAD,改动消失。
Environment
- OS: Windows 11 25H2 (10.0.26200)
- Node.js:
v22.22.2 - teamai:
0.24.0 - Provider: Gitee(走泛型 provider)
- AI tool(s): WorkBuddy / CodeBuddy
Suggested fix
- 提供落到默认分支的能力(本 issue 的核心诉求)。 例如
teamai push --direct(直接推默认分支,可要求二次确认),或teamai push --branch <name>指定目标分支。当前push只接受--all/--skill/--role/--project,用户完全没有办法让变更进默认分支,只能绕开 CLI 手搓git——这恰恰是 CLI 想避免的事。 - PR 不可用时要"响",并给出下一步。 provider 无法自动创建 PR 时,不要只打一行错误就结束。至少要把推送分支名、以及一条可直接执行的
git push origin HEAD:<default>或者"请在 上为分支 X 创建 PR"的提示打出来。现在的输出让人以为事情已经办完了。 - 不要对用户的工作区做
reset --hard/clean -fd。 动手前先检测脏工作区:有未提交改动就中止(或先 stash 并在结束后恢复),至少要有明确警告。这一步是静默且不可逆的。
Activity
[-][bug] `teamai push` 永远只推 teamai/push/<user>/<ts> 分支:泛型 Git host 上 PR 建不起来导致提交悬空,且该分支可能携带删除远端资源的破坏性变更[/-][+][bug] `teamai push` 无法指定目标分支:Gitee 等泛型 host 上 CLI 不会自动建 PR,新资源会悬空在 teamai/push/* 分支上(过程中还有一次 hard reset)[/+]CarlosWonMore commentedon Sep 19, 2026
更正:本 issue 早前版本里「分支携带破坏性删除」那段是错的,已删除
我把两处论证搞错了,先说结论再说原因。
错在哪
早前版本里我写了「分支相对 master 为
907 insertions(+), 4618 deletions(-),包含删除skills/team-wiki-codebase/*,合并会丢掉 4618 行资源」。这个结论不成立。我用的命令是两点差异:
git diff --stat master..teamai/push/C/20260919-173548 # 我错误地引用了这个而那条分支早就是 master 的祖先(它的 PR 已经合并),此时两点差异的方向是反的——master
在后来的提交里新增的一切,在这个方向上都会表现为「删除」。正确的提法应当是三点差异,它衡量的是
分支相对 merge-base 的真实贡献:
三点差异为空,即那条分支相对 master 没有任何新增内容,更谈不上删除。
另一条分支同样复核了,是纯新增、零删除:
所以「
push会把本地缺失的远端资源当成应当删除」这个机制没有证据支持,我已从正文删除。抱歉制造了噪音——提 issue 时把差异方向搞反是我的失误,尤其是这类会引发恐慌的结论,
本应先用
master...branch复核再写。保留不变的部分
本 issue 的核心仍然是成立的,且与上面无关:
push --help只有--all/--skill/--role/--project,没有指定目标分支的开关;gitee命中,且是 GitCode 的注释),因此 Gitee 走泛型 provider,PR 创建抛
Automatic pull/merge request creation is not supported for generic Git hosts.;906 insertions(+)的 2 个新 skill)没有任何 PR 被创建,分支在远端悬空,CLI 也没提示需要用户手动去开 PR。对比第一次推送的 PR sync: v0.16.3 from internal #1 之所以合并了,
是因为那个 PR 是手工在 Gitee 上建的(17:38:38 创建、17:39:10 合并),不是 CLI 建的;
reset --hard HEAD(reflog 可查),静默丢弃了我未提交的改动。jeff-r2026 commentedon Sep 20, 2026
Support adding
--branchon the existingpushcommand. Do not add--direct.teamai push --branch <name>should let the user name the destination instead of always creatingteamai/push/<user>/<timestamp>. PR creation still follows the provider. On a generic host that cannot open a PR, keep the current failure path: the branch is pushed, print the branch name and that a PR has to be created by hand, and return a non-zero exit.Separately: do not
reset --hard/clean -fdover a dirty working tree. If there are modified or untracked files, abort before those git operations and list the paths. Do not silently discard the user's uncommitted work.