diff --git a/apps/mobile/src/state/use-selected-thread-git-state.test.tsx b/apps/mobile/src/state/use-selected-thread-git-state.test.tsx
new file mode 100644
index 0000000000000..73c3b22d02abe
--- /dev/null
+++ b/apps/mobile/src/state/use-selected-thread-git-state.test.tsx
@@ -0,0 +1,106 @@
+import * as NodeChildProcess from "node:child_process";
+import * as NodeFS from "node:fs";
+import * as NodeOS from "node:os";
+import * as NodePath from "node:path";
+import { act, useLayoutEffect } from "react";
+import { createRoot } from "react-dom/client";
+import { expect, it, vi } from "vite-plus/test";
+
+const harness = vi.hoisted(() => ({
+ root: "",
+ cwd: "",
+}));
+
+vi.mock("./use-thread-selection", () => ({
+ useThreadSelection: () => ({
+ selectedThread: { environmentId: "environment-1" },
+ selectedThreadProject: { workspaceRoot: harness.root },
+ }),
+}));
+vi.mock("./use-selected-thread-worktree", () => ({
+ useSelectedThreadWorktree: () => ({ selectedThreadCwd: harness.cwd }),
+}));
+vi.mock("./use-vcs-action-state", () => ({
+ useVcsActionState: () => ({ currentLabel: null }),
+}));
+vi.mock("./sourceControl", () => ({
+ sourceControlEnvironment: { discovery: () => null },
+}));
+vi.mock("./query", () => ({ useEnvironmentQuery: () => ({ data: null }) }));
+vi.mock("./queries", () => ({
+ useBranches: ({ cwd }: { cwd: string }) => ({
+ data: {
+ refs: NodeChildProcess.execFileSync(
+ "git",
+ ["for-each-ref", "--format=%(refname:short) %(HEAD)", "refs/heads"],
+ {
+ cwd,
+ encoding: "utf8",
+ },
+ )
+ .trim()
+ .split("\n")
+ .map((line) => ({
+ name: line.split(" ")[0],
+ current: line.endsWith("*"),
+ isRemote: false,
+ })),
+ },
+ isPending: false,
+ }),
+}));
+
+import { useSelectedThreadGitState } from "./use-selected-thread-git-state";
+
+it("marks the selected checkout's branch current when switching threads in one project", () => {
+ const directory = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "mobile-branches-"));
+ const git = (...args: string[]) =>
+ NodeChildProcess.execFileSync("git", ["-c", "commit.gpgsign=false", ...args], {
+ cwd: directory,
+ encoding: "utf8",
+ stdio: "pipe",
+ });
+ const root = createRoot(document.createElement("div"));
+ (globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
+ let currentBranches: string[] = [];
+ function Consumer() {
+ const { selectedThreadBranches } = useSelectedThreadGitState();
+ useLayoutEffect(() => {
+ currentBranches = selectedThreadBranches
+ .filter((branch) => branch.current)
+ .map((branch) => branch.name);
+ }, [selectedThreadBranches]);
+ return null;
+ }
+
+ try {
+ git("init", "--initial-branch=main");
+ git(
+ "-c",
+ "user.name=Test",
+ "-c",
+ "user.email=test@example.com",
+ "commit",
+ "--allow-empty",
+ "-m",
+ "initial",
+ );
+ const worktree = NodePath.join(directory, "linked");
+ git("worktree", "add", "-b", "feature/mobile", worktree);
+ harness.root = directory;
+ harness.cwd = directory;
+ act(() => root.render());
+ expect(currentBranches).toEqual(["main"]);
+
+ harness.cwd = worktree;
+ act(() => root.render());
+ expect(currentBranches).toEqual(["feature/mobile"]);
+
+ harness.cwd = directory;
+ act(() => root.render());
+ expect(currentBranches).toEqual(["main"]);
+ } finally {
+ act(() => root.unmount());
+ NodeFS.rmSync(directory, { recursive: true, force: true });
+ }
+});
diff --git a/apps/mobile/src/state/use-selected-thread-git-state.ts b/apps/mobile/src/state/use-selected-thread-git-state.ts
index e8b3339c79493..e9a961b152fed 100644
--- a/apps/mobile/src/state/use-selected-thread-git-state.ts
+++ b/apps/mobile/src/state/use-selected-thread-git-state.ts
@@ -10,7 +10,7 @@ import { useThreadSelection } from "./use-thread-selection";
import { useSelectedThreadWorktree } from "./use-selected-thread-worktree";
export function useSelectedThreadGitState() {
- const { selectedThread, selectedThreadProject } = useThreadSelection();
+ const { selectedThread } = useThreadSelection();
const { selectedThreadCwd } = useSelectedThreadWorktree();
const selectedThreadGitTarget = {
@@ -29,7 +29,7 @@ export function useSelectedThreadGitState() {
const selectedThreadBranchTarget = {
environmentId: selectedThread?.environmentId ?? null,
- cwd: selectedThreadProject?.workspaceRoot ?? null,
+ cwd: selectedThreadCwd,
query: null,
};
const selectedThreadBranchState = useBranches(selectedThreadBranchTarget);
diff --git a/apps/mobile/vite.config.ts b/apps/mobile/vite.config.ts
index 9ddb84efbc832..d64a6cb8ca27e 100644
--- a/apps/mobile/vite.config.ts
+++ b/apps/mobile/vite.config.ts
@@ -28,6 +28,7 @@ const reactTests = [
"src/native/useRetryingImageSource.test.tsx",
"src/state/queries.debounce.test.tsx",
"src/state/use-selected-thread-git-actions.test.tsx",
+ "src/state/use-selected-thread-git-state.test.tsx",
"src/features/terminal/useTerminalExitNavigation.test.tsx",
"src/features/threads/use-thread-list-now.test.tsx",
"src/features/home/home-list-options.test.tsx",