Skip to content

Commit e815d38

Browse files
authored
feat(git): show which checkout the branch picker targets
The BranchSelector popover gets a context row ("Branch in <folder>" in local mode, "Base branch for <folder>" in worktree mode, full path on hover) and the trigger tooltip gains the checkout path, so switching a branch with multiple checkouts of the same repo is unambiguous. Uses the existing cross-platform getFileName helper, and switches the sidebar worktree chip's name derivation to it as well (fixes full-path chip labels on Windows). Generated-By: PostHog Code Task-Id: 783b5974-b3ee-4b5e-9ff6-fbc93a6794c5
1 parent 30ea90d commit e815d38

3 files changed

Lines changed: 84 additions & 6 deletions

File tree

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,57 @@ describe("BranchSelector cloud mode", () => {
165165
expect(onCloudBranchCommit).toHaveBeenCalledTimes(1);
166166
});
167167
});
168+
169+
describe("BranchSelector checkout context", () => {
170+
it.each([
171+
{
172+
name: "local mode shows which checkout the branch switch applies to",
173+
workspaceMode: "local" as const,
174+
expectedPrefix: "Branch in",
175+
},
176+
{
177+
name: "worktree mode labels the pick as the base branch for the checkout",
178+
workspaceMode: "worktree" as const,
179+
expectedPrefix: "Base branch for",
180+
},
181+
])("$name", async ({ workspaceMode, expectedPrefix }) => {
182+
const user = userEvent.setup();
183+
renderInTheme(
184+
<BranchSelector
185+
repoPath="/repos/code-wt"
186+
currentBranch="main"
187+
workspaceMode={workspaceMode}
188+
onBranchSelect={vi.fn()}
189+
/>,
190+
);
191+
192+
await user.click(screen.getByRole("combobox", { name: "Branch" }));
193+
194+
const contextRow = await screen.findByText(expectedPrefix, {
195+
exact: false,
196+
});
197+
expect(contextRow).toHaveTextContent(`${expectedPrefix} code-wt`);
198+
expect(contextRow).toHaveAttribute("title", "/repos/code-wt");
199+
});
200+
201+
it("shows no checkout row in cloud mode (the repo picker sits next to it)", async () => {
202+
const user = userEvent.setup();
203+
renderInTheme(
204+
<BranchSelector
205+
repoPath="owner/repo"
206+
currentBranch={null}
207+
workspaceMode="cloud"
208+
cloudBranches={["main"]}
209+
cloudBranchesLoading={false}
210+
cloudSearchQuery=""
211+
onBranchSelect={vi.fn()}
212+
onCloudSearchChange={vi.fn()}
213+
/>,
214+
);
215+
216+
await user.click(screen.getByRole("combobox", { name: "Branch" }));
217+
218+
expect(screen.queryByText("Branch in", { exact: false })).toBeNull();
219+
expect(screen.queryByText("Base branch for", { exact: false })).toBeNull();
220+
});
221+
});

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
InputGroupAddon,
2222
InputGroupButton,
2323
} from "@posthog/quill";
24+
import { getFileName } from "@posthog/shared";
2425
import type {
2526
GitBusyOperation,
2627
GitBusyState,
@@ -196,6 +197,11 @@ export function BranchSelector({
196197
? busyOperationLabel
197198
: (displayedBranch ?? "No branch");
198199

200+
// Which checkout the branch applies to. With several checkouts of the same
201+
// repo registered (main clone + worktrees), a bare branch name is ambiguous
202+
// — in local mode picking one runs a real checkout in this directory.
203+
const checkoutName = !isCloudMode && repoPath ? getFileName(repoPath) : null;
204+
199205
const showSpinner =
200206
effectiveLoading || (isCloudMode && open && cloudBranchesFetchingMore);
201207

@@ -295,7 +301,17 @@ export function BranchSelector({
295301
filter={isCloudMode ? null : undefined}
296302
>
297303
<Tooltip
298-
content={disabledReason ?? displayedBranch ?? "Switch branch"}
304+
content={
305+
disabledReason ??
306+
(checkoutName && repoPath ? (
307+
<span className="flex flex-col">
308+
<span>{displayedBranch ?? "Switch branch"}</span>
309+
<span className="text-gray-10">in {repoPath}</span>
310+
</span>
311+
) : (
312+
(displayedBranch ?? "Switch branch")
313+
))
314+
}
299315
side="bottom"
300316
open={hovered && !open && !effectiveLoading}
301317
>
@@ -405,6 +421,16 @@ export function BranchSelector({
405421
</InputGroupAddon>
406422
</ComboboxInput>
407423

424+
{checkoutName ? (
425+
<div
426+
className="truncate border-border border-b px-2 py-1.5 text-muted-foreground text-xs"
427+
title={repoPath ?? undefined}
428+
>
429+
{isSelectionOnly ? "Base branch for " : "Branch in "}
430+
<span className="font-medium">{checkoutName}</span>
431+
</div>
432+
) : null}
433+
408434
{isCloudMode && cloudBranchesFetchingMore ? (
409435
<LoadingRow label={`Loading more (${branches.length})…`} />
410436
) : null}

packages/ui/src/features/sidebar/components/TaskListView.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
TaskGroup,
1313
} from "@posthog/core/sidebar/sidebarData.types";
1414
import { MenuLabel } from "@posthog/quill";
15+
import { getFileName } from "@posthog/shared";
1516
import { builderHog } from "@posthog/ui/assets/hedgehogs";
1617
import { useFolders } from "@posthog/ui/features/folders/useFolders";
1718
import { useArchivingTasksStore } from "@posthog/ui/features/sidebar/archivingTasksStore";
@@ -100,18 +101,15 @@ function TaskRow({
100101
const worktreeCheckout = useMemo(() => {
101102
if (workspace?.worktreePath) {
102103
return {
103-
name:
104-
workspace.worktreeName ??
105-
workspace.worktreePath.split("/").pop() ??
106-
workspace.worktreePath,
104+
name: workspace.worktreeName ?? getFileName(workspace.worktreePath),
107105
path: workspace.worktreePath,
108106
};
109107
}
110108
if (workspace?.mode === "local" && workspace.folderPath) {
111109
const folder = folders.find((f) => f.path === workspace.folderPath);
112110
if (folder?.mainRepoPath) {
113111
return {
114-
name: workspace.folderPath.split("/").pop() ?? workspace.folderPath,
112+
name: getFileName(workspace.folderPath),
115113
path: workspace.folderPath,
116114
};
117115
}

0 commit comments

Comments
 (0)