






















@@ -386,7 +386,7 @@ describe("runGatewayUpdate", () => {
386386{ name: "target ref", options: { devTargetRef: "main" } },
387387] as const)("stops dev update when fetch fails before resolving $name", async ({ options }) => {
388388await setupGitCheckout();
389-const fetchCommand = `git -C ${tempDir} fetch --all --prune --tags`;
389+const fetchCommand = `git -C ${tempDir} fetch --all --prune --no-tags`;
390390const { runner, calls } = createRunner({
391391 ...buildGitWorktreeProbeResponses(),
392392[fetchCommand]: {
@@ -403,6 +403,102 @@ describe("runGatewayUpdate", () => {
403403expect(calls.slice(calls.indexOf(fetchCommand) + 1)).toStrictEqual([]);
404404});
405405406+it("does not fetch tags for dev updates", async () => {
407+await setupGitPackageManagerFixture();
408+const upstreamSha = "upstream123";
409+const doctorNodePath = await resolveStableNodePath(process.execPath);
410+const doctorCommand = `${doctorNodePath} ${path.join(tempDir, "openclaw.mjs")} doctor --non-interactive --fix`;
411+const { runner, calls } = createRunner({
412+ ...buildGitWorktreeProbeResponses(),
413+[`git -C ${tempDir} fetch --all --prune --no-tags`]: { stdout: "" },
414+[`git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`]: {
415+stdout: "origin/main",
416+},
417+[`git -C ${tempDir} rev-parse @{upstream}`]: { stdout: upstreamSha },
418+[`git -C ${tempDir} rev-list --max-count=10 ${upstreamSha}`]: {
419+stdout: `${upstreamSha}\n`,
420+},
421+[`git -C ${tempDir} rebase ${upstreamSha}`]: { stdout: "" },
422+"pnpm --version": { stdout: "10.0.0" },
423+"pnpm install": { stdout: "" },
424+"pnpm build": { stdout: "" },
425+"pnpm ui:build": { stdout: "" },
426+[doctorCommand]: { stdout: "" },
427+});
428+429+const result = await runWithRunner(runner, { channel: "dev" });
430+431+expect(result.status).toBe("ok");
432+expect(calls).toContain(`git -C ${tempDir} fetch --all --prune --no-tags`);
433+expect(calls).not.toContain(`git -C ${tempDir} fetch --all --prune --tags`);
434+});
435+436+it("fetches only the requested tag for explicit dev tag target refs", async () => {
437+await setupGitPackageManagerFixture();
438+const targetSha = "2222222222222222222222222222222222222222";
439+const doctorNodePath = await resolveStableNodePath(process.execPath);
440+const doctorCommand = `${doctorNodePath} ${path.join(tempDir, "openclaw.mjs")} doctor --non-interactive --fix`;
441+const { runner, calls } = createRunner({
442+ ...buildGitWorktreeProbeResponses(),
443+[`git -C ${tempDir} fetch --all --prune --no-tags`]: { stdout: "" },
444+[`git -C ${tempDir} remote`]: { stdout: "origin\n" },
445+[`git -C ${tempDir} fetch origin +refs/tags/v2026.5.19-beta.2:refs/tags/v2026.5.19-beta.2`]: {
446+stdout: "",
447+},
448+[`git -C ${tempDir} rev-parse refs/tags/v2026.5.19-beta.2^{}`]: {
449+stdout: `${targetSha}\n`,
450+},
451+[`git -C ${tempDir} rev-list --max-count=10 ${targetSha}`]: {
452+stdout: `${targetSha}\n`,
453+},
454+[`git -C ${tempDir} checkout --detach ${targetSha}`]: { stdout: "" },
455+"pnpm --version": { stdout: "10.0.0" },
456+"pnpm install": { stdout: "" },
457+"pnpm build": { stdout: "" },
458+"pnpm ui:build": { stdout: "" },
459+[doctorCommand]: { stdout: "" },
460+});
461+462+const result = await runWithRunner(runner, {
463+channel: "dev",
464+devTargetRef: "refs/tags/v2026.5.19-beta.2",
465+});
466+467+expect(result.status).toBe("ok");
468+expect(calls).toContain(`git -C ${tempDir} fetch --all --prune --no-tags`);
469+expect(calls).not.toContain(`git -C ${tempDir} fetch --all --prune --tags`);
470+expect(calls).toContain(
471+`git -C ${tempDir} fetch origin +refs/tags/v2026.5.19-beta.2:refs/tags/v2026.5.19-beta.2`,
472+);
473+expect(calls).toContain(`git -C ${tempDir} rev-parse refs/tags/v2026.5.19-beta.2^{}`);
474+});
475+476+it("does not resolve stale local dev tag target refs after targeted tag fetch failure", async () => {
477+await setupGitCheckout();
478+const { runner, calls } = createRunner({
479+ ...buildGitWorktreeProbeResponses(),
480+[`git -C ${tempDir} fetch --all --prune --no-tags`]: { stdout: "" },
481+[`git -C ${tempDir} remote`]: { stdout: "origin\n" },
482+[`git -C ${tempDir} fetch origin +refs/tags/v2026.5.19-beta.2:refs/tags/v2026.5.19-beta.2`]: {
483+code: 1,
484+stderr: "would clobber existing tag",
485+},
486+});
487+488+const result = await runWithRunner(runner, {
489+channel: "dev",
490+devTargetRef: "refs/tags/v2026.5.19-beta.2",
491+});
492+493+expect(result.status).toBe("error");
494+expect(result.reason).toBe("no-target-sha");
495+expect(calls).toContain(
496+`git -C ${tempDir} fetch origin +refs/tags/v2026.5.19-beta.2:refs/tags/v2026.5.19-beta.2`,
497+);
498+expect(calls).not.toContain(`git -C ${tempDir} rev-parse refs/tags/v2026.5.19-beta.2^{}`);
499+expect(calls).not.toContain(`git -C ${tempDir} rev-parse refs/tags/v2026.5.19-beta.2`);
500+});
501+406502it("aborts rebase on failure", async () => {
407503await setupGitCheckout();
408504const { runner, calls } = createRunner({
@@ -537,7 +633,7 @@ describe("runGatewayUpdate", () => {
537633if (key === `git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`) {
538634return { stdout: "origin/main", stderr: "", code: 0 };
539635}
540-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
636+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
541637return { stdout: "", stderr: "", code: 0 };
542638}
543639if (key === `git -C ${tempDir} rev-parse @{upstream}`) {
@@ -758,7 +854,7 @@ describe("runGatewayUpdate", () => {
758854if (key === `git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`) {
759855return { stdout: "origin/main", stderr: "", code: 0 };
760856}
761-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
857+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
762858return { stdout: "", stderr: "", code: 0 };
763859}
764860if (key === `git -C ${tempDir} rev-parse @{upstream}`) {
@@ -873,7 +969,7 @@ describe("runGatewayUpdate", () => {
873969if (key === `git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`) {
874970return { stdout: "origin/main", stderr: "", code: 0 };
875971}
876-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
972+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
877973return { stdout: "", stderr: "", code: 0 };
878974}
879975if (key === `git -C ${tempDir} rev-parse @{upstream}`) {
@@ -970,7 +1066,7 @@ describe("runGatewayUpdate", () => {
9701066if (key === `git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`) {
9711067return { stdout: "origin/main", stderr: "", code: 0 };
9721068}
973-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
1069+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
9741070return { stdout: "", stderr: "", code: 0 };
9751071}
9761072if (key === `git -C ${tempDir} rev-parse @{upstream}`) {
@@ -1084,7 +1180,7 @@ describe("runGatewayUpdate", () => {
10841180if (key === `git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`) {
10851181return { stdout: "origin/main", stderr: "", code: 0 };
10861182}
1087-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
1183+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
10881184return { stdout: "", stderr: "", code: 0 };
10891185}
10901186if (key === `git -C ${tempDir} rev-parse @{upstream}`) {
@@ -1182,7 +1278,7 @@ describe("runGatewayUpdate", () => {
11821278if (key === `git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`) {
11831279return { stdout: "origin/main", stderr: "", code: 0 };
11841280}
1185-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
1281+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
11861282return { stdout: "", stderr: "", code: 0 };
11871283}
11881284if (key === `git -C ${tempDir} rev-parse @{upstream}`) {
@@ -1275,7 +1371,7 @@ describe("runGatewayUpdate", () => {
12751371if (key === `git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`) {
12761372return { stdout: "origin/main", stderr: "", code: 0 };
12771373}
1278-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
1374+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
12791375return { stdout: "", stderr: "", code: 0 };
12801376}
12811377if (key === `git -C ${tempDir} rev-parse @{upstream}`) {
@@ -1367,7 +1463,7 @@ describe("runGatewayUpdate", () => {
13671463if (key === `git -C ${tempDir} status --porcelain -- :!dist/control-ui/`) {
13681464return { stdout: "", stderr: "", code: 0 };
13691465}
1370-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
1466+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
13711467return { stdout: "", stderr: "", code: 0 };
13721468}
13731469if (key === `git -C ${tempDir} rev-parse ${targetSha}`) {
@@ -1447,7 +1543,7 @@ describe("runGatewayUpdate", () => {
14471543if (key === `git -C ${tempDir} status --porcelain -- :!dist/control-ui/`) {
14481544return { stdout: "", stderr: "", code: 0 };
14491545}
1450-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
1546+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
14511547return { stdout: "", stderr: "", code: 0 };
14521548}
14531549if (key === `git -C ${tempDir} rev-parse refs/remotes/origin/main`) {
@@ -1530,7 +1626,7 @@ describe("runGatewayUpdate", () => {
15301626if (key === `git -C ${gitRoot} status --porcelain -- :!dist/control-ui/`) {
15311627return { stdout: "", stderr: "", code: 0 };
15321628}
1533-if (key === `git -C ${gitRoot} fetch --all --prune --tags`) {
1629+if (key === `git -C ${gitRoot} fetch --all --prune --no-tags`) {
15341630return { stdout: "", stderr: "", code: 0 };
15351631}
15361632if (key === `git -C ${gitRoot} rev-parse refs/remotes/origin/main`) {
@@ -1606,7 +1702,7 @@ describe("runGatewayUpdate", () => {
16061702if (key === `git -C ${tempDir} rev-parse --abbrev-ref --symbolic-full-name @{upstream}`) {
16071703return { stdout: "origin/main", stderr: "", code: 0 };
16081704}
1609-if (key === `git -C ${tempDir} fetch --all --prune --tags`) {
1705+if (key === `git -C ${tempDir} fetch --all --prune --no-tags`) {
16101706return { stdout: "", stderr: "", code: 0 };
16111707}
16121708if (key === `git -C ${tempDir} rev-parse @{upstream}`) {
此內容由慣性聚合(RSS閱讀器)自動聚合整理,僅供閱讀參考。 原文來自 — 版權歸原作者所有。