Show Git-created worktrees in external discovery (#7078)
This commit is contained in:
parent
1ac6de1ccb
commit
4c03924618
|
|
@ -1402,13 +1402,9 @@ export function registerWorktreeHandlers(
|
|||
if (!registeredWorktree) {
|
||||
const fsProvider = repo.connectionId ? getSshFilesystemProvider(repo.connectionId) : null
|
||||
let canCleanOrphanedDirectory = false
|
||||
const knownOrcaLayouts = buildKnownOrcaWorkspaceLayouts(store.getSettings(), repo)
|
||||
if (
|
||||
canCleanupUnregisteredOrcaWorktreeDirectory({
|
||||
meta: removedMeta,
|
||||
worktreePath,
|
||||
repo,
|
||||
knownOrcaLayouts
|
||||
meta: removedMeta
|
||||
})
|
||||
) {
|
||||
if (repo.connectionId) {
|
||||
|
|
@ -1481,7 +1477,6 @@ export function registerWorktreeHandlers(
|
|||
runtimeWorktreePath,
|
||||
repo,
|
||||
runtimeRepoPath: toLocalWorktreeRuntimePath(repo.path, localWorktreeGitOptions),
|
||||
knownOrcaLayouts,
|
||||
registeredWorktrees,
|
||||
statPath: access.statPath,
|
||||
isGitRepository: (path) => isLocalGitRepository(path, localWorktreeGitOptions)
|
||||
|
|
|
|||
|
|
@ -14713,13 +14713,9 @@ export class OrcaRuntimeService {
|
|||
)
|
||||
if (!registeredWorktree) {
|
||||
let canCleanOrphanedDirectory = false
|
||||
const knownOrcaLayouts = buildKnownOrcaWorkspaceLayouts(store.getSettings(), repo)
|
||||
if (
|
||||
canCleanupUnregisteredOrcaWorktreeDirectory({
|
||||
meta: removedMeta,
|
||||
worktreePath: removalTarget.path,
|
||||
repo,
|
||||
knownOrcaLayouts
|
||||
meta: removedMeta
|
||||
})
|
||||
) {
|
||||
if (repo.connectionId) {
|
||||
|
|
@ -14792,7 +14788,6 @@ export class OrcaRuntimeService {
|
|||
runtimeWorktreePath,
|
||||
repo,
|
||||
runtimeRepoPath: toLocalWorktreeRuntimePath(repo.path, localWorktreeGitOptions),
|
||||
knownOrcaLayouts,
|
||||
registeredWorktrees,
|
||||
statPath: access.statPath,
|
||||
isGitRepository: (path) => isLocalRuntimeGitRepository(path, localWorktreeGitOptions)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import {
|
|||
isWorktreePathMissing,
|
||||
stripOrcaProvenanceMetaUpdates
|
||||
} from './worktree-removal-safety'
|
||||
import type { WorktreeMeta } from '../shared/types'
|
||||
|
||||
describe('isWorktreePathMissing', () => {
|
||||
it('recognizes missing-path errors from local and remote stat providers', async () => {
|
||||
|
|
@ -33,10 +34,7 @@ describe('canCleanupUnregisteredOrcaWorktreeDirectory', () => {
|
|||
it('does not treat orcaCreatedAt alone as cleanup authority', () => {
|
||||
expect(
|
||||
canCleanupUnregisteredOrcaWorktreeDirectory({
|
||||
meta: { orcaCreatedAt: Date.now() },
|
||||
worktreePath: '/outside/orphan',
|
||||
repo: { path: '/repo' },
|
||||
knownOrcaLayouts: []
|
||||
meta: { orcaCreatedAt: Date.now() }
|
||||
})
|
||||
).toBe(false)
|
||||
expect(
|
||||
|
|
@ -44,10 +42,7 @@ describe('canCleanupUnregisteredOrcaWorktreeDirectory', () => {
|
|||
meta: {
|
||||
orcaCreatedAt: Date.now(),
|
||||
orcaCreationSource: 'runtime'
|
||||
},
|
||||
worktreePath: '/outside/orphan',
|
||||
repo: { path: '/repo' },
|
||||
knownOrcaLayouts: []
|
||||
}
|
||||
})
|
||||
).toBe(true)
|
||||
})
|
||||
|
|
@ -55,32 +50,40 @@ describe('canCleanupUnregisteredOrcaWorktreeDirectory', () => {
|
|||
it('accepts legacy Orca-created metadata before explicit provenance existed', () => {
|
||||
expect(
|
||||
canCleanupUnregisteredOrcaWorktreeDirectory({
|
||||
meta: { createdAt: Date.now() },
|
||||
worktreePath: '/outside/orphan',
|
||||
repo: { path: '/repo' },
|
||||
knownOrcaLayouts: []
|
||||
meta: { createdAt: Date.now() }
|
||||
})
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
it('accepts legacy repo-nested Orca workspace paths without metadata provenance', () => {
|
||||
it('does not treat creation layout metadata alone as cleanup authority', () => {
|
||||
const layoutOnlyMeta: WorktreeMeta = {
|
||||
displayName: '',
|
||||
comment: '',
|
||||
linkedIssue: null,
|
||||
linkedPR: null,
|
||||
linkedLinearIssue: null,
|
||||
linkedGitLabMR: null,
|
||||
linkedGitLabIssue: null,
|
||||
isArchived: false,
|
||||
isUnread: false,
|
||||
isPinned: false,
|
||||
sortOrder: 0,
|
||||
lastActivityAt: 0,
|
||||
workspaceStatus: 'todo',
|
||||
orcaCreationWorkspaceLayout: { path: '/orca/workspaces', nestWorkspaces: true }
|
||||
}
|
||||
|
||||
expect(
|
||||
canCleanupUnregisteredOrcaWorktreeDirectory({
|
||||
meta: undefined,
|
||||
worktreePath: '/orca/workspaces/app/legacy-orphan',
|
||||
repo: { path: '/repos/app' },
|
||||
knownOrcaLayouts: [{ path: '/orca/workspaces', nestWorkspaces: true }]
|
||||
meta: layoutOnlyMeta
|
||||
})
|
||||
).toBe(true)
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it('does not trust flat workspace-root paths without legacy metadata', () => {
|
||||
it('does not trust paths without provenance or legacy metadata', () => {
|
||||
expect(
|
||||
canCleanupUnregisteredOrcaWorktreeDirectory({
|
||||
meta: undefined,
|
||||
worktreePath: '/orca/workspaces/legacy-orphan',
|
||||
repo: { path: '/repos/app' },
|
||||
knownOrcaLayouts: [{ path: '/orca/workspaces', nestWorkspaces: false }]
|
||||
meta: undefined
|
||||
})
|
||||
).toBe(false)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -325,7 +325,6 @@ describe('canCleanupUnregisteredOrcaLeftoverDirectory', () => {
|
|||
runtimeWorktreePath: '/workspaces/orca-owned',
|
||||
repo,
|
||||
runtimeRepoPath: repo.path,
|
||||
knownOrcaLayouts: [],
|
||||
registeredWorktrees: [makeGitWorktree(repo.path, true)]
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +375,6 @@ describe('canCleanupUnregisteredOrcaLeftoverDirectory', () => {
|
|||
canCleanupUnregisteredOrcaLeftoverDirectory({
|
||||
...baseArgs,
|
||||
meta: undefined,
|
||||
knownOrcaLayouts: [{ path: '/workspaces', nestWorkspaces: false }],
|
||||
statPath: makeStatPath([], ['/workspaces/orca-owned']),
|
||||
isGitRepository
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ import { lstat, readFile } from 'node:fs/promises'
|
|||
import { homedir } from 'node:os'
|
||||
import { posix, win32 } from 'node:path'
|
||||
import { isWindowsAbsolutePathLike } from '../shared/cross-platform-path'
|
||||
import type { GitWorktreeInfo, OrcaWorkspaceLayout, Repo, WorktreeMeta } from '../shared/types'
|
||||
import { matchesStrongOrcaCreatePath } from '../shared/worktree-ownership'
|
||||
import type { GitWorktreeInfo, Repo, WorktreeMeta } from '../shared/types'
|
||||
import { areWorktreePathsEqual } from './ipc/worktree-logic'
|
||||
import {
|
||||
gitFileProvesOrphanedWorktreeDirectory,
|
||||
|
|
@ -172,9 +171,6 @@ export async function canSafelyRemoveOrphanedWorktreeDirectory(
|
|||
|
||||
export function canCleanupUnregisteredOrcaWorktreeDirectory(args: {
|
||||
meta: UnregisteredOrcaCleanupMeta | null | undefined
|
||||
worktreePath: string
|
||||
repo: Pick<Repo, 'path'>
|
||||
knownOrcaLayouts: readonly OrcaWorkspaceLayout[]
|
||||
}): boolean {
|
||||
if (hasCurrentOrcaCreationProvenance(args.meta)) {
|
||||
return true
|
||||
|
|
@ -184,9 +180,9 @@ export function canCleanupUnregisteredOrcaWorktreeDirectory(args: {
|
|||
return true
|
||||
}
|
||||
|
||||
// Why: profiles created before explicit provenance can still contain Orca
|
||||
// workspaces at the repo-specific workspaceDir/<repo>/<name> path shape.
|
||||
return matchesStrongOrcaCreatePath(args.worktreePath, args.knownOrcaLayouts, args.repo)
|
||||
// Why: path shape alone is not authority; users can create plain Git
|
||||
// worktrees inside Orca's workspace directory too.
|
||||
return false
|
||||
}
|
||||
|
||||
export async function canCleanupUnregisteredOrcaLeftoverDirectory(args: {
|
||||
|
|
@ -195,7 +191,6 @@ export async function canCleanupUnregisteredOrcaLeftoverDirectory(args: {
|
|||
runtimeWorktreePath: string
|
||||
repo: Pick<Repo, 'path'>
|
||||
runtimeRepoPath: string
|
||||
knownOrcaLayouts: readonly OrcaWorkspaceLayout[]
|
||||
registeredWorktrees: readonly GitWorktreeInfo[]
|
||||
statPath: StatPath
|
||||
isGitRepository: (runtimeWorktreePath: string) => Promise<boolean>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import type { DetectedWorktree, DetectedWorktreeListResult, Repo } from './types'
|
||||
import type {
|
||||
DetectedWorktree,
|
||||
DetectedWorktreeListResult,
|
||||
GlobalSettings,
|
||||
Repo,
|
||||
Worktree
|
||||
} from './types'
|
||||
import {
|
||||
getHiddenExternalWorktrees,
|
||||
getNewExternalWorktreeInboxWorktrees,
|
||||
mergeExternalWorktreeInboxPaths,
|
||||
shouldOfferNewExternalWorktreeInbox
|
||||
} from './external-worktree-inbox'
|
||||
import { EXTERNAL_WORKTREE_VISIBILITY_ROLLOUT_AT } from './worktree-ownership'
|
||||
import {
|
||||
buildKnownOrcaWorkspaceLayouts,
|
||||
EXTERNAL_WORKTREE_VISIBILITY_ROLLOUT_AT,
|
||||
toDetectedWorktree
|
||||
} from './worktree-ownership'
|
||||
|
||||
const repo: Repo = {
|
||||
id: 'repo-1',
|
||||
|
|
@ -54,6 +64,55 @@ function detectedResult(worktrees: DetectedWorktree[]): DetectedWorktreeListResu
|
|||
}
|
||||
}
|
||||
|
||||
function makeSettings(): GlobalSettings {
|
||||
return {
|
||||
workspaceDir: '/orca/workspaces',
|
||||
nestWorkspaces: true,
|
||||
workspaceDirHistory: [],
|
||||
refreshLocalBaseRefOnWorktreeCreate: false,
|
||||
localBaseRefSuggestionDismissed: false,
|
||||
branchPrefix: 'none',
|
||||
branchPrefixCustom: '',
|
||||
enableGitHubAttribution: false,
|
||||
theme: 'system',
|
||||
appFontFamily: 'Geist',
|
||||
editorAutoSave: false,
|
||||
editorAutoSaveDelayMs: 1000,
|
||||
editorMinimapEnabled: false,
|
||||
markdownReviewToolsEnabled: true,
|
||||
terminalFontSize: 14,
|
||||
terminalFontFamily: 'monospace',
|
||||
terminalFontWeight: 400,
|
||||
terminalLineHeight: 1.2
|
||||
} as unknown as GlobalSettings
|
||||
}
|
||||
|
||||
function makeGitWorktree(overrides: Partial<Worktree> = {}): Worktree {
|
||||
return {
|
||||
id: `repo-1::${overrides.path ?? '/repo'}`,
|
||||
repoId: repo.id,
|
||||
path: '/repo',
|
||||
displayName: 'repo',
|
||||
branch: 'refs/heads/main',
|
||||
head: 'abc123',
|
||||
isBare: false,
|
||||
isMainWorktree: true,
|
||||
comment: '',
|
||||
linkedIssue: null,
|
||||
linkedPR: null,
|
||||
linkedLinearIssue: null,
|
||||
linkedGitLabMR: null,
|
||||
linkedGitLabIssue: null,
|
||||
isArchived: false,
|
||||
isUnread: false,
|
||||
isPinned: false,
|
||||
sortOrder: 0,
|
||||
lastActivityAt: 0,
|
||||
workspaceStatus: 'todo',
|
||||
...overrides
|
||||
}
|
||||
}
|
||||
|
||||
describe('external worktree inbox', () => {
|
||||
it('merges inbox paths without duplicates when paths match after normalization', () => {
|
||||
expect(mergeExternalWorktreeInboxPaths(['/repo/one/'], ['/repo/one', '/repo/two'])).toEqual([
|
||||
|
|
@ -103,6 +162,25 @@ describe('external worktree inbox', () => {
|
|||
).toEqual([hidden])
|
||||
})
|
||||
|
||||
it('offers metadata-free nested Orca workspace worktrees through the inbox', () => {
|
||||
const settings = makeSettings()
|
||||
const manual = toDetectedWorktree({
|
||||
repo,
|
||||
settings,
|
||||
worktree: makeGitWorktree({
|
||||
path: '/orca/workspaces/orca/manual-from-git',
|
||||
displayName: 'manual-from-git',
|
||||
branch: 'refs/heads/manual-from-git',
|
||||
isMainWorktree: false
|
||||
}),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
|
||||
expect(manual.ownership).toBe('external')
|
||||
expect(manual.visible).toBe(false)
|
||||
expect(getNewExternalWorktreeInboxWorktrees(detectedResult([manual]), repo)).toEqual([manual])
|
||||
})
|
||||
|
||||
it('suppresses non-authoritative detected results', () => {
|
||||
expect(
|
||||
getNewExternalWorktreeInboxWorktrees(detectedResult([detectedWorktree()]), {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ describe('repo-specific worktree ownership layouts', () => {
|
|||
worktree: makeWorktree('/projects/a/worktrees/repo/feature'),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repoA)
|
||||
})
|
||||
).toBe('orca-managed')
|
||||
).toBe('external')
|
||||
expect(
|
||||
classifyWorktreeOwnership({
|
||||
repo: repoB,
|
||||
|
|
@ -73,7 +73,7 @@ describe('repo-specific worktree ownership layouts', () => {
|
|||
worktree: makeWorktree('C:\\projects\\App\\worktrees\\repo\\Feature'),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
).toBe('orca-managed')
|
||||
).toBe('external')
|
||||
})
|
||||
|
||||
it('includes relative global layouts for SSH repos without applying absolute desktop paths', () => {
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ describe('worktree ownership classification', () => {
|
|||
).toBe('orca-managed')
|
||||
})
|
||||
|
||||
it('requires the nested repo-specific path shape for path-only ownership', () => {
|
||||
it('treats nested Orca workspace paths without metadata as external', () => {
|
||||
const repo = makeRepo()
|
||||
const settings = makeSettings()
|
||||
const layouts = buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
|
|
@ -119,7 +119,7 @@ describe('worktree ownership classification', () => {
|
|||
worktree: makeWorktree({ path: '/orca/workspaces/app/feature' }),
|
||||
knownOrcaLayouts: layouts
|
||||
})
|
||||
).toBe('orca-managed')
|
||||
).toBe('external')
|
||||
expect(
|
||||
classifyWorktreeOwnership({
|
||||
repo,
|
||||
|
|
@ -130,6 +130,94 @@ describe('worktree ownership classification', () => {
|
|||
).toBe('external')
|
||||
})
|
||||
|
||||
it('treats explicit Orca creation layout metadata as managed', () => {
|
||||
const repo = makeRepo()
|
||||
const settings = makeSettings()
|
||||
expect(
|
||||
classifyWorktreeOwnership({
|
||||
repo,
|
||||
settings,
|
||||
worktree: makeWorktree({ path: '/orca/workspaces/app/feature' }),
|
||||
meta: makeMeta({
|
||||
orcaCreationWorkspaceLayout: { path: '/orca/workspaces', nestWorkspaces: true }
|
||||
}),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
).toBe('orca-managed')
|
||||
})
|
||||
|
||||
it('does not treat metadata-free nested workspace paths as Orca-managed for new repos', () => {
|
||||
const repo = makeRepo({ externalWorktreeVisibility: 'hide' })
|
||||
const settings = makeSettings()
|
||||
const detected = toDetectedWorktree({
|
||||
repo,
|
||||
settings,
|
||||
worktree: makeWorktree({
|
||||
path: '/orca/workspaces/app/manual-git-worktree',
|
||||
isMainWorktree: false
|
||||
}),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
|
||||
expect(detected.ownership).toBe('external')
|
||||
expect(detected.visible).toBe(false)
|
||||
})
|
||||
|
||||
it('does not treat generic discovery metadata on nested workspace paths as Orca-managed', () => {
|
||||
const repo = makeRepo({ externalWorktreeVisibility: 'hide' })
|
||||
const settings = makeSettings()
|
||||
const detected = toDetectedWorktree({
|
||||
repo,
|
||||
settings,
|
||||
worktree: makeWorktree({
|
||||
path: '/orca/workspaces/app/manual-git-worktree',
|
||||
isMainWorktree: false
|
||||
}),
|
||||
meta: makeMeta({ displayName: 'manual-git-worktree' }),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
|
||||
expect(detected.ownership).toBe('external')
|
||||
expect(detected.visible).toBe(false)
|
||||
})
|
||||
|
||||
it('keeps nested workspace paths visible for legacy repos without explicit visibility', () => {
|
||||
const repo = makeRepo()
|
||||
const settings = makeSettings()
|
||||
const detected = toDetectedWorktree({
|
||||
repo,
|
||||
settings,
|
||||
worktree: makeWorktree({
|
||||
path: '/orca/workspaces/app/manual-git-worktree',
|
||||
isMainWorktree: false
|
||||
}),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
|
||||
expect(detected.ownership).toBe('external')
|
||||
expect(detected.visible).toBe(true)
|
||||
})
|
||||
|
||||
it('hides metadata-free nested workspace paths for legacy repos that hide external worktrees', () => {
|
||||
const repo = makeRepo({
|
||||
externalWorktreeVisibility: 'hide',
|
||||
externalWorktreeVisibilityLegacy: true
|
||||
})
|
||||
const settings = makeSettings()
|
||||
const detected = toDetectedWorktree({
|
||||
repo,
|
||||
settings,
|
||||
worktree: makeWorktree({
|
||||
path: '/orca/workspaces/app/manual-git-worktree',
|
||||
isMainWorktree: false
|
||||
}),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
|
||||
expect(detected.ownership).toBe('external')
|
||||
expect(detected.visible).toBe(false)
|
||||
})
|
||||
|
||||
it('treats flat workspace-root descendants as unknown legacy without strong metadata', () => {
|
||||
const repo = makeRepo()
|
||||
const settings = makeSettings({ nestWorkspaces: false })
|
||||
|
|
@ -172,7 +260,7 @@ describe('worktree ownership classification', () => {
|
|||
worktree: makeWorktree({ path: '/old/workspaces/app/feature' }),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
).toBe('orca-managed')
|
||||
).toBe('external')
|
||||
})
|
||||
|
||||
it('builds known layouts from large workspace history lists', () => {
|
||||
|
|
@ -214,7 +302,7 @@ describe('worktree ownership classification', () => {
|
|||
}),
|
||||
knownOrcaLayouts: buildKnownOrcaWorkspaceLayouts(settings, repo)
|
||||
})
|
||||
).toBe('orca-managed')
|
||||
).toBe('external')
|
||||
})
|
||||
|
||||
it('keeps selected linked checkouts visible without trusting Git main-worktree', () => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
getRuntimePathBasename,
|
||||
isRuntimePathAbsolute,
|
||||
isWindowsAbsolutePathLike,
|
||||
normalizeRuntimePathForComparison,
|
||||
|
|
@ -160,15 +159,13 @@ export function classifyWorktreeOwnership(args: {
|
|||
return 'orca-managed'
|
||||
}
|
||||
|
||||
if (matchesStrongOrcaCreatePath(args.worktree.path, args.knownOrcaLayouts, args.repo)) {
|
||||
return 'orca-managed'
|
||||
}
|
||||
|
||||
if (isUnderFlatOrUntrustedOrcaRoot(args.worktree.path, args.knownOrcaLayouts)) {
|
||||
return 'unknown-legacy'
|
||||
}
|
||||
|
||||
if (canClassifyAsExternal(args.worktree.path, args.knownOrcaLayouts)) {
|
||||
// Why: a plain `git worktree add` can target Orca's nested workspace
|
||||
// folder. Only metadata proves Orca created it.
|
||||
return 'external'
|
||||
}
|
||||
|
||||
|
|
@ -240,6 +237,7 @@ export function areRuntimePathsEqual(leftPath: string, rightPath: string): boole
|
|||
function hasStrongOrcaMetadata(meta: WorktreeMeta | undefined): boolean {
|
||||
return Boolean(
|
||||
meta?.orcaCreatedAt ||
|
||||
meta?.orcaCreationWorkspaceLayout ||
|
||||
meta?.createdAt ||
|
||||
meta?.createdWithAgent ||
|
||||
meta?.pushTarget ||
|
||||
|
|
@ -249,38 +247,6 @@ function hasStrongOrcaMetadata(meta: WorktreeMeta | undefined): boolean {
|
|||
)
|
||||
}
|
||||
|
||||
export function matchesStrongOrcaCreatePath(
|
||||
worktreePath: string,
|
||||
knownOrcaLayouts: readonly OrcaWorkspaceLayout[],
|
||||
repo: Pick<Repo, 'path'>
|
||||
): boolean {
|
||||
const repoName = getRuntimePathBasename(repo.path).replace(/\.git$/i, '')
|
||||
if (!repoName) {
|
||||
return false
|
||||
}
|
||||
for (const layout of knownOrcaLayouts) {
|
||||
if (!layout.nestWorkspaces) {
|
||||
continue
|
||||
}
|
||||
const relative = relativePathInsideRoot(layout.path, worktreePath)
|
||||
if (relative === null) {
|
||||
continue
|
||||
}
|
||||
const segments = splitNormalizedPath(relative)
|
||||
const caseInsensitive =
|
||||
isWindowsAbsolutePathLike(layout.path) || isWindowsAbsolutePathLike(worktreePath)
|
||||
if (
|
||||
segments.length === 2 &&
|
||||
normalizePathSegment(segments[0], caseInsensitive) ===
|
||||
normalizePathSegment(repoName, caseInsensitive) &&
|
||||
segments[1].length > 0
|
||||
) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function isUnderFlatOrUntrustedOrcaRoot(
|
||||
worktreePath: string,
|
||||
knownOrcaLayouts: OrcaWorkspaceLayout[]
|
||||
|
|
@ -313,12 +279,3 @@ function canClassifyAsExternal(
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function splitNormalizedPath(value: string): string[] {
|
||||
return normalizeRuntimePathSeparators(value).split('/').filter(Boolean)
|
||||
}
|
||||
|
||||
function normalizePathSegment(value: string, caseInsensitive: boolean): string {
|
||||
const normalized = normalizeRuntimePathSeparators(value)
|
||||
return caseInsensitive ? normalized.toLowerCase() : normalized
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue