Skip to content

Commit dec9229

Browse files
authored
fix(git): reflect in-place branch checkout (#3760)
1 parent 0d728bc commit dec9229

2 files changed

Lines changed: 77 additions & 3 deletions

File tree

packages/ui/src/features/git-interaction/components/BranchSelector.test.tsx

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Theme } from "@radix-ui/themes";
2-
import { render, screen } from "@testing-library/react";
2+
import { act, render, screen } from "@testing-library/react";
33
import userEvent from "@testing-library/user-event";
4+
import { useState } from "react";
45
import { describe, expect, it, vi } from "vitest";
56

67
vi.mock("../state/gitInteractionStore", () => ({
@@ -42,9 +43,36 @@ vi.mock("../../../primitives/toast", () => ({
4243
}));
4344

4445
const mutateMock = vi.fn();
46+
let checkoutMutationOptions: {
47+
onSuccess?: (result: {
48+
previousBranch: string;
49+
currentBranch: string;
50+
}) => void;
51+
};
52+
let completeCheckout: (result: {
53+
previousBranch: string;
54+
currentBranch: string;
55+
}) => void;
4556
vi.mock("@tanstack/react-query", () => ({
4657
useQuery: () => ({ data: [], isLoading: false }),
47-
useMutation: () => ({ mutate: mutateMock }),
58+
useMutation: (options: typeof checkoutMutationOptions) => {
59+
checkoutMutationOptions = options;
60+
const [result, setResult] = useState<{
61+
data?: { previousBranch: string; currentBranch: string };
62+
variables?: { directoryPath: string; branchName: string };
63+
}>({});
64+
completeCheckout = (data) => {
65+
setResult({
66+
data,
67+
variables: {
68+
directoryPath: "/repos/code",
69+
branchName: data.currentBranch,
70+
},
71+
});
72+
options.onSuccess?.(data);
73+
};
74+
return { mutate: mutateMock, ...result };
75+
},
4876
useQueryClient: () => ({
4977
getQueriesData: () => [],
5078
getQueryData: () => undefined,
@@ -297,6 +325,45 @@ describe("BranchSelector cloud mode", () => {
297325
});
298326

299327
describe("BranchSelector checkout context", () => {
328+
it("shows the checked-out branch after an in-place checkout succeeds", () => {
329+
const { rerender } = renderInTheme(
330+
<BranchSelector
331+
repoPath="/repos/code"
332+
currentBranch="main"
333+
workspaceMode="local"
334+
/>,
335+
);
336+
337+
expect(screen.getByRole("combobox", { name: "Branch" })).toHaveTextContent(
338+
"main",
339+
);
340+
341+
act(() => {
342+
completeCheckout({
343+
previousBranch: "main",
344+
currentBranch: "feature/in-place",
345+
});
346+
});
347+
348+
expect(screen.getByRole("combobox", { name: "Branch" })).toHaveTextContent(
349+
"feature/in-place",
350+
);
351+
352+
rerender(
353+
<Theme>
354+
<BranchSelector
355+
repoPath="/repos/code"
356+
currentBranch="feature/external"
357+
workspaceMode="local"
358+
/>
359+
</Theme>,
360+
);
361+
362+
expect(screen.getByRole("combobox", { name: "Branch" })).toHaveTextContent(
363+
"feature/external",
364+
);
365+
});
366+
300367
it.each([
301368
{
302369
name: "local mode shows which checkout the branch switch applies to",

packages/ui/src/features/git-interaction/components/BranchSelector.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ export function BranchSelector({
142142

143143
const isCloudMode = workspaceMode === "cloud";
144144
const isSelectionOnly = workspaceMode === "worktree" || isCloudMode;
145-
const displayedBranch = isSelectionOnly ? selectedBranch : currentBranch;
146145

147146
// The branch we auto-selected, so we can tell our own pick apart from one the
148147
// user made. Lets us correct a stale default (e.g. a cached "trunk" that the
@@ -233,6 +232,14 @@ export function BranchSelector({
233232
},
234233
});
235234

235+
const checkedOutBranch =
236+
checkoutMutation.data &&
237+
checkoutMutation.variables.directoryPath === repoPath &&
238+
currentBranch === checkoutMutation.data.previousBranch
239+
? checkoutMutation.data.currentBranch
240+
: currentBranch;
241+
const displayedBranch = isSelectionOnly ? selectedBranch : checkedOutBranch;
242+
236243
// In local mode, surface in-progress git operations (rebase/merge/etc.) so the
237244
// user understands why there's no current branch and why we won't let them
238245
// checkout a different one — checkout would fail with a hard-to-read git error.

0 commit comments

Comments
 (0)