@@ -347,24 +347,58 @@ export async function getHostMountFolder(cliHost: CLIHost, folderPath: string, m
347347export interface WorkspaceConfiguration {
348348 workspaceMount : string | undefined ;
349349 workspaceFolder : string | undefined ;
350+ additionalMountString : string | undefined ;
350351}
351352
352353export async function getWorkspaceConfiguration ( cliHost : CLIHost , workspace : Workspace | undefined , config : DevContainerConfig , mountWorkspaceGitRoot : boolean , output : Log , consistency ?: BindMountConsistency ) : Promise < WorkspaceConfiguration > {
353354 if ( 'dockerComposeFile' in config ) {
354355 return {
355356 workspaceFolder : getRemoteWorkspaceFolder ( config ) ,
356357 workspaceMount : undefined ,
358+ additionalMountString : undefined ,
357359 } ;
358360 }
359361 let { workspaceFolder, workspaceMount } = config ;
362+ let additionalMountString : string | undefined ;
360363 if ( workspace && ( ! workspaceFolder || ! ( 'workspaceMount' in config ) ) ) {
361364 const hostMountFolder = await getHostMountFolder ( cliHost , workspace . rootFolderPath , mountWorkspaceGitRoot , output ) ;
365+
366+ // Check if .git is a file (worktree) with a relative gitdir path
367+ let containerMountFolder = path . posix . join ( '/workspaces' , cliHost . path . basename ( hostMountFolder ) ) ;
368+ if ( mountWorkspaceGitRoot ) {
369+ const dotGitPath = cliHost . path . join ( hostMountFolder , '.git' ) ;
370+ if ( await cliHost . isFile ( dotGitPath ) ) {
371+ const dotGitContent = ( await cliHost . readFile ( dotGitPath ) ) . toString ( ) ;
372+ const match = / ^ g i t d i r : \s * ( .+ ) $ / m. exec ( dotGitContent ) ;
373+ if ( match ) {
374+ const gitdir = match [ 1 ] ;
375+ // Only handle if gitdir is a relative path
376+ if ( ! cliHost . path . isAbsolute ( gitdir ) ) {
377+ // gitdir points to .git/worktrees/<name>/, common dir is .git/ (two levels up)
378+ const gitCommonDir = cliHost . path . resolve ( hostMountFolder , gitdir , '..' , '..' ) ;
379+ // Collect path segments from hostMountFolder up to the parent of gitCommonDir
380+ const segments : string [ ] = [ ] ;
381+ for ( let current = hostMountFolder ; ! gitCommonDir . startsWith ( current + cliHost . path . sep ) && current !== cliHost . path . dirname ( current ) ; current = cliHost . path . dirname ( current ) ) {
382+ segments . unshift ( cliHost . path . basename ( current ) ) ;
383+ }
384+ containerMountFolder = path . posix . join ( '/workspaces' , ...segments ) ;
385+ // Calculate where the common dir should be mounted in the container
386+ const containerGitdir = cliHost . platform === 'win32' ? gitdir . replace ( / \\ / g, '/' ) : gitdir ;
387+ const containerGitCommonDir = path . posix . resolve ( containerMountFolder , containerGitdir , '..' , '..' ) ;
388+ const cons = cliHost . platform !== 'linux' ? `,consistency=${ consistency || 'consistent' } ` : '' ;
389+ const srcQuote = gitCommonDir . indexOf ( ',' ) !== - 1 ? '"' : '' ;
390+ const tgtQuote = containerGitCommonDir . indexOf ( ',' ) !== - 1 ? '"' : '' ;
391+ additionalMountString = `type=bind,${ srcQuote } source=${ gitCommonDir } ${ srcQuote } ,${ tgtQuote } target=${ containerGitCommonDir } ${ tgtQuote } ${ cons } ` ;
392+ }
393+ }
394+ }
395+ }
396+
362397 if ( ! workspaceFolder ) {
363- const rel = cliHost . path . relative ( cliHost . path . dirname ( hostMountFolder ) , workspace . rootFolderPath ) ;
364- workspaceFolder = `/workspaces/ ${ cliHost . platform === 'win32' ? rel . replace ( / \\ / g, '/' ) : rel } ` ;
398+ const rel = cliHost . path . relative ( hostMountFolder , workspace . rootFolderPath ) ;
399+ workspaceFolder = path . posix . join ( containerMountFolder , cliHost . platform === 'win32' ? rel . replace ( / \\ / g, '/' ) : rel ) ;
365400 }
366401 if ( ! ( 'workspaceMount' in config ) ) {
367- const containerMountFolder = `/workspaces/${ cliHost . path . basename ( hostMountFolder ) } ` ;
368402 const cons = cliHost . platform !== 'linux' ? `,consistency=${ consistency || 'consistent' } ` : '' ; // Podman does not tolerate consistency=
369403 const srcQuote = hostMountFolder . indexOf ( ',' ) !== - 1 ? '"' : '' ;
370404 const tgtQuote = containerMountFolder . indexOf ( ',' ) !== - 1 ? '"' : '' ;
@@ -374,6 +408,7 @@ export async function getWorkspaceConfiguration(cliHost: CLIHost, workspace: Wor
374408 return {
375409 workspaceFolder,
376410 workspaceMount,
411+ additionalMountString,
377412 } ;
378413}
379414
0 commit comments