diff --git a/apps/web/src/components/GitActionsControl.logic.test.ts b/apps/web/src/components/GitActionsControl.logic.test.ts
index 0bd7e49b3286a182ef44cc1681ee57980f7e4633..25ad553d1deb7d68135908d27e0916c0b6b2dd21 100644
--- a/apps/web/src/components/GitActionsControl.logic.test.ts
+++ b/apps/web/src/components/GitActionsControl.logic.test.ts
@@ -1,6 +1,7 @@
import type { GitStatusResult } from "@t3tools/contracts";
import { assert, describe, it } from "vitest";
import {
+ buildGitActionProgressStages,
buildMenuItems,
requiresDefaultBranchConfirmation,
resolveQuickAction,
@@ -596,6 +597,27 @@ describe("requiresDefaultBranchConfirmation", () => {
});
});
+describe("buildGitActionProgressStages", () => {
+ it("shows only push progress when push-only is forced", () => {
+ const stages = buildGitActionProgressStages({
+ action: "commit_push",
+ hasCustomCommitMessage: false,
+ hasWorkingTreeChanges: true,
+ forcePushOnly: true,
+ });
+ assert.deepEqual(stages, ["Pushing..."]);
+ });
+
+ it("includes commit stages for commit+push when working tree is dirty", () => {
+ const stages = buildGitActionProgressStages({
+ action: "commit_push",
+ hasCustomCommitMessage: false,
+ hasWorkingTreeChanges: true,
+ });
+ assert.deepEqual(stages, ["Generating commit message...", "Committing...", "Pushing..."]);
+ });
+});
+
describe("summarizeGitResult", () => {
it("returns commit-focused toast for commit action", () => {
const result = summarizeGitResult({
diff --git a/apps/web/src/components/GitActionsControl.logic.ts b/apps/web/src/components/GitActionsControl.logic.ts
index d00fcbc740b5090fa5e45df6649e4d9f64689ac3..ebab3cbf5a8ed7921003a8f17a0e60ed1602aeb4 100644
--- a/apps/web/src/components/GitActionsControl.logic.ts
+++ b/apps/web/src/components/GitActionsControl.logic.ts
@@ -43,6 +43,28 @@ function truncateText(
return `${value.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
}
+export function buildGitActionProgressStages(input: {
+ action: GitStackedAction;
+ hasCustomCommitMessage: boolean;
+ hasWorkingTreeChanges: boolean;
+ forcePushOnly?: boolean;
+}): string[] {
+ const shouldIncludeCommitStages =
+ !input.forcePushOnly && (input.action === "commit" || input.hasWorkingTreeChanges);
+ const commitStages = !shouldIncludeCommitStages
+ ? []
+ : input.hasCustomCommitMessage
+ ? ["Committing..."]
+ : ["Generating commit message...", "Committing..."];
+ if (input.action === "commit") {
+ return commitStages;
+ }
+ if (input.action === "commit_push") {
+ return [...commitStages, "Pushing..."];
+ }
+ return [...commitStages, "Pushing...", "Creating PR..."];
+}
+
export function summarizeGitResult(result: GitRunStackedActionResult): {
title: string;
description?: string;
diff --git a/apps/web/src/components/GitActionsControl.tsx b/apps/web/src/components/GitActionsControl.tsx
index c9c84f41bba60a552062784be0a2a564c819a7ee..49d3d82a976c2a1cc457970d7578710506a35faa 100644
--- a/apps/web/src/components/GitActionsControl.tsx
+++ b/apps/web/src/components/GitActionsControl.tsx
@@ -4,6 +4,7 @@ import { useCallback, useMemo, useState } from "react";
import { ChevronDownIcon, CloudUploadIcon, GitCommitIcon, InfoIcon } from "lucide-react";
import { GitHubIcon } from "./Icons";
import {
+ buildGitActionProgressStages,
buildMenuItems,
type GitActionIconName,
type GitActionMenuItem,
@@ -134,26 +135,6 @@ function GitQuickActionIcon({ quickAction }: { quickAction: GitQuickAction }) {
return ;
}
-function buildGitActionProgressStages(input: {
- action: GitStackedAction;
- hasCustomCommitMessage: boolean;
- hasWorkingTreeChanges: boolean;
-}): string[] {
- const shouldIncludeCommitStages = input.action === "commit" || input.hasWorkingTreeChanges;
- const commitStages = !shouldIncludeCommitStages
- ? []
- : input.hasCustomCommitMessage
- ? ["Committing..."]
- : ["Generating commit message...", "Committing..."];
- if (input.action === "commit") {
- return commitStages;
- }
- if (input.action === "commit_push") {
- return [...commitStages, "Pushing..."];
- }
- return [...commitStages, "Pushing...", "Creating PR..."];
-}
-
export default function GitActionsControl({ api, gitCwd }: GitActionsControlProps) {
const queryClient = useQueryClient();
const [activeDialogAction, setActiveDialogAction] = useState(null);
@@ -230,7 +211,15 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
}, [api, gitStatus?.openPr?.url]);
const runGitActionWithToast = useCallback(
- async ({ action, commitMessage }: { action: GitStackedAction; commitMessage?: string }) => {
+ async ({
+ action,
+ commitMessage,
+ forcePushOnlyProgress = false,
+ }: {
+ action: GitStackedAction;
+ commitMessage?: string;
+ forcePushOnlyProgress?: boolean;
+ }) => {
const confirmed = await maybeConfirmPushToDefaultBranch(action);
if (!confirmed) return;
@@ -238,6 +227,7 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
action,
hasCustomCommitMessage: !!commitMessage?.trim(),
hasWorkingTreeChanges: !!gitStatus?.hasWorkingTreeChanges,
+ forcePushOnly: forcePushOnlyProgress,
});
const progressToastId = toastManager.add({
type: "loading",
@@ -290,7 +280,10 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
children: "Push",
onClick: () => {
closeResultToast();
- void runGitActionWithToast({ action: "commit_push" });
+ void runGitActionWithToast({
+ action: "commit_push",
+ forcePushOnlyProgress: true,
+ });
},
},
}
@@ -381,7 +374,7 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
return;
}
if (item.dialogAction === "push") {
- void runGitActionWithToast({ action: "commit_push" });
+ void runGitActionWithToast({ action: "commit_push", forcePushOnlyProgress: true });
return;
}
if (item.dialogAction) {
@@ -400,10 +393,12 @@ export default function GitActionsControl({ api, gitCwd }: GitActionsControlProp
? "commit_push"
: "commit_push_pr";
const commitMessage = activeDialogAction === "commit" ? dialogCommitMessage.trim() : "";
+ const forcePushOnlyProgress = activeDialogAction === "push";
setActiveDialogAction(null);
void runGitActionWithToast({
action,
...(commitMessage ? { commitMessage } : {}),
+ ...(forcePushOnlyProgress ? { forcePushOnlyProgress } : {}),
});
}, [activeDialogAction, dialogCommitMessage, runGitActionWithToast]);