authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-03-01 11:34:36-08:00
committergravatar for jmarminge@gmail.comJulius Marminge <jmarminge@gmail.com> 2026-03-01 20:06:01-08:00
logc8974ede6dc26b931c89d7415b9cbdd534aa8de4
tree6d3520c890113050acc1f87e215cb90b5db02934
parent0c637e3d5ec54b79b3df72b074b998ddc439b14a

refactor: dedupe git action new-branch flow

Co-authored-by: codex <codex@users.noreply.github.com>

1 files changed, 54 insertions(+), 76 deletions(-)

apps/web/src/components/GitActionsControl.tsx+54-76
......@@ -400,95 +400,73 @@ export default function GitActionsControl({ gitCwd, activeThreadId }: GitActions
400400 });
401401 }, [pendingDefaultBranchAction, runGitActionWithToast]);
402402
403 const checkoutNewBranchAndRunAction = useCallback(
404 (actionParams: {
405 action: GitStackedAction;
406 commitMessage?: string;
407 forcePushOnlyProgress?: boolean;
408 onConfirmed?: () => void;
409 }) => {
410 const branchName = resolveAutoFeatureBranchName(
411 branchList?.branches.map((branch) => branch.name) ?? [],
412 );
413
414 const checkoutPromise = createBranchAndCheckoutMutation.mutateAsync(branchName);
415 toastManager.promise(checkoutPromise, {
416 loading: { title: `Creating ${branchName}...`, data: threadToastData },
417 success: () => ({
418 title: `Checked out ${branchName}`,
419 data: threadToastData,
420 }),
421 error: (error) => ({
422 title: "Failed to checkout feature branch",
423 description: error instanceof Error ? error.message : "An error occurred.",
424 data: threadToastData,
425 }),
426 });
427
428 void checkoutPromise
429 .then(() => {
430 const statusOverride = gitStatusForActions
431 ? { ...gitStatusForActions, branch: branchName, pr: null }
432 : null;
433 return runGitActionWithToast({
434 ...actionParams,
435 skipDefaultBranchPrompt: true,
436 statusOverride,
437 isDefaultBranchOverride: false,
438 });
439 })
440 .catch(() => undefined);
441 },
442 [
443 branchList?.branches,
444 createBranchAndCheckoutMutation,
445 gitStatusForActions,
446 runGitActionWithToast,
447 threadToastData,
448 ],
449 );
450
403451 const checkoutFeatureBranchAndContinuePendingAction = useCallback(() => {
404452 if (!pendingDefaultBranchAction) return;
405453 const pendingAction = pendingDefaultBranchAction;
406 const branchName = resolveAutoFeatureBranchName(branchList?.branches.map((branch) => branch.name) ?? []);
407454 setPendingDefaultBranchAction(null);
408
409 const checkoutPromise = createBranchAndCheckoutMutation.mutateAsync(branchName);
410 toastManager.promise(checkoutPromise, {
411 loading: { title: `Creating ${branchName}...`, data: threadToastData },
412 success: () => ({
413 title: `Checked out ${branchName}`,
414 data: threadToastData,
415 }),
416 error: (error) => ({
417 title: "Failed to checkout feature branch",
418 description: error instanceof Error ? error.message : "An error occurred.",
419 data: threadToastData,
420 }),
421 });
422
423 void checkoutPromise
424 .then(() => {
425 const statusOverride = gitStatusForActions
426 ? { ...gitStatusForActions, branch: branchName, pr: null }
427 : null;
428 return runGitActionWithToast({
429 ...pendingAction,
430 skipDefaultBranchPrompt: true,
431 statusOverride,
432 isDefaultBranchOverride: false,
433 });
434 })
435 .catch(() => undefined);
436 }, [
437 branchList?.branches,
438 createBranchAndCheckoutMutation,
439 gitStatusForActions,
440 pendingDefaultBranchAction,
441 runGitActionWithToast,
442 threadToastData,
443 ]);
455 checkoutNewBranchAndRunAction(pendingAction);
456 }, [pendingDefaultBranchAction, checkoutNewBranchAndRunAction]);
444457
445458 const runDialogActionOnNewBranch = useCallback(() => {
446459 if (!isCommitDialogOpen) return;
447 const action: GitStackedAction = "commit";
448460 const commitMessage = dialogCommitMessage.trim();
449 const branchName = resolveAutoFeatureBranchName(branchList?.branches.map((branch) => branch.name) ?? []);
450461
451462 setIsCommitDialogOpen(false);
452463 setDialogCommitMessage("");
453464
454 const checkoutPromise = createBranchAndCheckoutMutation.mutateAsync(branchName);
455 toastManager.promise(checkoutPromise, {
456 loading: { title: `Creating ${branchName}...`, data: threadToastData },
457 success: () => ({
458 title: `Checked out ${branchName}`,
459 data: threadToastData,
460 }),
461 error: (error) => ({
462 title: "Failed to checkout feature branch",
463 description: error instanceof Error ? error.message : "An error occurred.",
464 data: threadToastData,
465 }),
465 checkoutNewBranchAndRunAction({
466 action: "commit",
467 ...(commitMessage ? { commitMessage } : {}),
466468 });
467
468 void checkoutPromise
469 .then(() => {
470 const statusOverride = gitStatusForActions
471 ? { ...gitStatusForActions, branch: branchName, pr: null }
472 : null;
473 return runGitActionWithToast({
474 action,
475 ...(commitMessage ? { commitMessage } : {}),
476 skipDefaultBranchPrompt: true,
477 statusOverride,
478 isDefaultBranchOverride: false,
479 });
480 })
481 .catch(() => undefined);
482 }, [
483 branchList?.branches,
484 createBranchAndCheckoutMutation,
485 dialogCommitMessage,
486 gitStatusForActions,
487 isCommitDialogOpen,
488 runGitActionWithToast,
489 setIsCommitDialogOpen,
490 threadToastData,
491 ]);
469 }, [isCommitDialogOpen, dialogCommitMessage, checkoutNewBranchAndRunAction]);
492470
493471 const runQuickAction = useCallback(() => {
494472 if (quickAction.kind === "open_pr") {