Skip to content

[bug] teamai push 无法指定目标分支:Gitee 等泛型 host 上 CLI 不会自动建 PR,新资源会悬空在 teamai/push/* 分支上(过程中还有一次 hard reset) #663

Closed

Description

@CarlosWonMore

English summary — teamai push has 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 --help accepts only
--all / --skill / --role / --project: there is no option to push to the default branch.
Separately, a reset --hard HEAD runs 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(-), removing skills/team-wiki-codebase/*).
That claim was wrong and I have removed it. I compared with git 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
is git 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

  1. 团队仓库远端指向 Gitee(或任何非 GitHub/TGit 的泛型 host)。
  2. 本地准备一份有新内容的推送目标(例如一个新 skill),teamai push --all。
  3. 观察:
    • 分支 teamai/push/<user>/<ts> 出现在远端;
    • CLI 打印 Automatic pull/merge request creation is not supported for generic Git hosts.;
    • 没有 PR 被创建,变更不会进默认分支;CLI 也没有提示"请手动开 PR"。
  4. 若此时工作区有未提交改动,对照 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

  1. 提供落到默认分支的能力(本 issue 的核心诉求)。 例如 teamai push --direct(直接推默认分支,可要求二次确认),或 teamai push --branch <name> 指定目标分支。当前 push 只接受 --all/--skill/--role/--project,用户完全没有办法让变更进默认分支,只能绕开 CLI 手搓 git——这恰恰是 CLI 想避免的事。
  2. PR 不可用时要"响",并给出下一步。 provider 无法自动创建 PR 时,不要只打一行错误就结束。至少要把推送分支名、以及一条可直接执行的 git push origin HEAD:<default> 或者"请在 上为分支 X 创建 PR"的提示打出来。现在的输出让人以为事情已经办完了。
  3. 不要对用户的工作区做 reset --hard / clean -fd。 动手前先检测脏工作区:有未提交改动就中止(或先 stash 并在结束后恢复),至少要有明确警告。这一步是静默且不可逆的。

Activity

  1. changed the title [-][bug] `teamai push` 永远只推 teamai/push/<user>/<ts> 分支:泛型 Git host 上 PR 建不起来导致提交悬空,且该分支可能携带删除远端资源的破坏性变更[/-] [+][bug] `teamai push` 无法指定目标分支:Gitee 等泛型 host 上 CLI 不会自动建 PR,新资源会悬空在 teamai/push/* 分支上(过程中还有一次 hard reset)[/+] on Sep 19, 2026
  2. CarlosWonMore commented on Sep 19, 2026

    @CarlosWonMore
    ContributorAuthor

    更正:本 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 的真实贡献:

    $ git diff --stat master...teamai/push/C/20260919-173548
    (空)
    
    $ git merge-base --is-ancestor 74fc341 master && echo ancestor
    ancestor

    三点差异为空,即那条分支相对 master 没有任何新增内容,更谈不上删除。

    另一条分支同样复核了,是纯新增、零删除:

    $ git diff --stat master...teamai/push/C/20260919-190031
     4 files changed, 906 insertions(+)

    所以「push 会把本地缺失的远端资源当成应当删除」这个机制没有证据支持,我已从正文删除。
    抱歉制造了噪音——提 issue 时把差异方向搞反是我的失误,尤其是这类会引发恐慌的结论,
    本应先用 master...branch 复核再写。

    保留不变的部分

    本 issue 的核心仍然是成立的,且与上面无关:

    • push --help 只有 --all/--skill/--role/--project,没有指定目标分支的开关;
    • bundle 里没有 Gitee provider(全文仅一处 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 建的;
    • push 过程中存在一次 reset --hard HEAD(reflog 可查),静默丢弃了我未提交的改动。
  3. jeff-r2026 commented on Sep 20, 2026

    @jeff-r2026
    Collaborator

    Support adding --branch on the existing push command. Do not add --direct.

    teamai push --branch <name> should let the user name the destination instead of always creating teamai/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 -fd over 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions