fix: dedupe shared worktree ownership
Cherry-picked from claude branch 7b3bec48 (fix: dedupe shared worktree ownership and title sessions immediately). Only the worktree-dedupe half applies to main: partitionWorktreesByRegisteredProject and its callers (SessionSidebar, ElectronMiniChatApp, MobileApp, MobileSessionsSheet) plus tests and sidebar docs. The session-title half (title sessions immediately) remains on the claude branch: the session-title runtime and its claude-code transcript translator imports do not exist on main and cannot build there until the Claude harness lands.
This commit is contained in:
@@ -47,7 +47,11 @@ import { SessionNodeItem } from './sidebar/SessionNodeItem';
|
||||
import type { SessionNodeRenderExtras } from './sidebar/sessionNodeItemUtils';
|
||||
import { useUpdateStore } from '@/stores/useUpdateStore';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { listProjectWorktrees, worktreeMapsEqual } from '@/lib/worktrees/worktreeManager';
|
||||
import {
|
||||
listProjectWorktrees,
|
||||
partitionWorktreesByRegisteredProject,
|
||||
worktreeMapsEqual,
|
||||
} from '@/lib/worktrees/worktreeManager';
|
||||
import { checkIsGitRepository } from '@/lib/gitApi';
|
||||
import type { WorktreeMetadata } from '@/types/worktree';
|
||||
import type { SortableDragHandleProps } from './sidebar/sortableItems';
|
||||
@@ -564,8 +568,8 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const currentByProject = useSessionUIStore.getState().availableWorktreesByProject;
|
||||
const worktreesByProject = new Map(currentByProject);
|
||||
const knownWorktreesByProject = useSessionUIStore.getState().availableWorktreesByProject;
|
||||
const worktreesByProject = new Map(knownWorktreesByProject);
|
||||
const unresolvedProjectPaths = new Set<string>();
|
||||
|
||||
// Constrain fanout: previously `Promise.all(projects.map(...))` could
|
||||
@@ -618,16 +622,17 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
worktreesByProject.delete(projectPath);
|
||||
}
|
||||
}
|
||||
const allWorktrees = [...worktreesByProject.values()].flat();
|
||||
const partitionedWorktreesByProject = partitionWorktreesByRegisteredProject(projectEntries, worktreesByProject);
|
||||
const allWorktrees = [...partitionedWorktreesByProject.values()].flat();
|
||||
// Newly appearing worktrees sort to the top of their project's
|
||||
// worktree list (see worktreeFirstSeen.ts).
|
||||
recordWorktreesSeen(allWorktrees.map((worktree) => worktree.path), Date.now());
|
||||
|
||||
// Skip update if nothing changed — see worktreeMapsEqual JSDoc.
|
||||
if (!worktreeMapsEqual(worktreesByProject, currentByProject)) {
|
||||
if (!worktreeMapsEqual(partitionedWorktreesByProject, knownWorktreesByProject)) {
|
||||
useSessionUIStore.setState({
|
||||
availableWorktrees: allWorktrees,
|
||||
availableWorktreesByProject: worktreesByProject,
|
||||
availableWorktreesByProject: partitionedWorktreesByProject,
|
||||
});
|
||||
}
|
||||
setUnresolvedWorktreeProjectPaths(unresolvedProjectPaths);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
- Group-level PR-status polling/indicators and worktree-group drag-to-reorder were removed together with the worktree grouping level; `oc.sessions.groupOrder` is no longer read or written. Worktree PR/branch context lives in the Worktrees surface.
|
||||
- Root session menus can quickly create a worktree from the session directory's current branch and move the full session subtree there while idle.
|
||||
- Directory loading is demand-driven: the sidebar publishes one complete priority plan for all known project/worktree directories, while the sync layer owns bounded execution.
|
||||
- When multiple configured projects are checkouts of the same Git repository, exactly one project owns the shared worktree topology: the configured canonical primary root when present, otherwise the first configured source for that repository. Any worktree path that is also a configured project is omitted from subordinate worktree groups, so every directory has one sidebar location while remaining part of bootstrap demand.
|
||||
|
||||
## VS Code grouping
|
||||
|
||||
|
||||
Reference in New Issue
Block a user