History

Extract branch sync logic and limit sync to local mode

- move branch-sync decision into `BranchToolbar.logic.ts` - avoid auto-sync when env mode is `worktree` or thread has worktree path - add unit tests for sync and no-sync cases

Julius Marminge committed 9 months ago

Commit 3756bbf1 parent 73fa2d63 files · +96 −6Browse files

Unified · Split

3 files
  1. apps/web/src/components/BranchToolbar.logic.test.ts +56 −0
  2. apps/web/src/components/BranchToolbar.logic.ts +28 −0
  3. apps/web/src/components/BranchToolbar.tsx +12 −6
apps/web/src/components/BranchToolbar.logic.test.ts+56−0
@@ -0,0 +1,56 @@
1+import type { GitBranch } from "@t3tools/contracts";
2+import { describe, expect, it } from "vitest";
3+import { deriveSyncedLocalBranch } from "./BranchToolbar.logic";
4+
5+const branches: GitBranch[] = [
6+ {
7+ name: "main",
8+ current: true,
9+ isDefault: true,
10+ worktreePath: null,
11+ },
12+ {
13+ name: "feature/demo",
14+ current: false,
15+ isDefault: false,
16+ worktreePath: null,
17+ },
18+];
19+
20+describe("deriveSyncedLocalBranch", () => {
21+ it("syncs to git current branch in local mode", () => {
22+ const result = deriveSyncedLocalBranch({
23+ activeThreadId: "thread-1",
24+ activeWorktreePath: null,
25+ envMode: "local",
26+ activeThreadBranch: "feature/demo",
27+ queryBranches: branches,
28+ });
29+
30+ expect(result).toBe("main");
31+ });
32+
33+ it("does not sync when creating a new worktree", () => {
34+ const result = deriveSyncedLocalBranch({
35+ activeThreadId: "thread-1",
36+ activeWorktreePath: null,
37+ envMode: "worktree",
38+ activeThreadBranch: "feature/demo",
39+ queryBranches: branches,
40+ });
41+
42+ expect(result).toBeNull();
43+ });
44+
45+ it("does not sync when thread already targets a worktree path", () => {
46+ const result = deriveSyncedLocalBranch({
47+ activeThreadId: "thread-1",
48+ activeWorktreePath: "/tmp/repo/worktrees/feature-demo",
49+ envMode: "local",
50+ activeThreadBranch: "feature/demo",
51+ queryBranches: branches,
52+ });
53+
54+ expect(result).toBeNull();
55+ });
56+});
apps/web/src/components/BranchToolbar.logic.ts+28−0
@@ -0,0 +1,28 @@
1+import type { GitBranch } from "@t3tools/contracts";
2+
3+interface DeriveSyncedLocalBranchInput {
4+ activeThreadId: string | undefined;
5+ activeWorktreePath: string | null;
6+ envMode: "local" | "worktree";
7+ activeThreadBranch: string | null;
8+ queryBranches: GitBranch[] | undefined;
9+}
10+
11+export function deriveSyncedLocalBranch({
12+ activeThreadId,
13+ activeWorktreePath,
14+ envMode,
15+ activeThreadBranch,
16+ queryBranches,
17+}: DeriveSyncedLocalBranchInput): string | null {
18+ if (!activeThreadId || activeWorktreePath || envMode !== "local") {
19+ return null;
20+ }
21+
22+ const currentBranch = queryBranches?.find((branch) => branch.current);
23+ if (!currentBranch || currentBranch.name === activeThreadBranch) {
24+ return null;
25+ }
26+
27+ return currentBranch.name;
28+}
apps/web/src/components/BranchToolbar.tsx+12−6
@@ -9,6 +9,7 @@ import { · 8 unmodified lines
99 gitCreateBranchAndCheckoutMutationOptions,
1010 } from "../lib/gitReactQuery";
1111 import { useStore } from "../store";
12+import { deriveSyncedLocalBranch } from "./BranchToolbar.logic";
1213 import { Button } from "./ui/button";
1314 import {
1415 Combobox,
@@ -86,17 +87,22 @@ export default function BranchToolbar({ · 71 unmodified lines
8687 // Keep thread branch synced to git current branch for local threads.
8788 const queryBranches = branchesQuery.data?.branches;
8889 useEffect(() => {
89− if (!activeThreadId || activeWorktreePath) return;
90− const current = queryBranches?.find((branch) => branch.current);
91− if (!current) return;
92− if (current.name === activeThreadBranch) return;
90+ const syncedBranch = deriveSyncedLocalBranch({
91+ activeThreadId,
92+ activeWorktreePath,
93+ envMode,
94+ activeThreadBranch,
95+ queryBranches,
96+ });
97+ if (!syncedBranch) return;
98+
9399 dispatch({
94100 type: "SET_THREAD_BRANCH",
95101 threadId: activeThreadId,
96− branch: current.name,
102+ branch: syncedBranch,
97103 worktreePath: null,
98104 });
99− }, [activeThreadId, activeWorktreePath, activeThreadBranch, queryBranches, dispatch]);
105+ }, [activeThreadId, activeWorktreePath, activeThreadBranch, queryBranches, envMode, dispatch]);
100106
101107 useEffect(() => {
102108 if (isBranchMenuOpen) return;