@@ -119,6 +119,26 @@ function New-ClaudeEnvJson
119119 $claudeEnv [" IS_TEAMCITY_AGENT" ] = $env: IS_TEAMCITY_AGENT
120120 }
121121
122+ # Git identity - read from host git config if not set in environment
123+ $gitUserName = $env: GIT_USER_NAME
124+ $gitUserEmail = $env: GIT_USER_EMAIL
125+ if (-not $gitUserName )
126+ {
127+ $gitUserName = git config -- global user.name
128+ }
129+ if (-not $gitUserEmail )
130+ {
131+ $gitUserEmail = git config -- global user.email
132+ }
133+ if ($gitUserName )
134+ {
135+ $claudeEnv [" GIT_USER_NAME" ] = $gitUserName
136+ }
137+ if ($gitUserEmail )
138+ {
139+ $claudeEnv [" GIT_USER_EMAIL" ] = $gitUserEmail
140+ }
141+
122142 # Convert to JSON and save
123143 $jsonPath = Join-Path $dockerContextDirectory " env.g.json"
124144
@@ -367,6 +387,22 @@ $MountPoints = $MountPoints | ForEach-Object { Get-ContainerPath $_ }
367387$GitDirectories = $GitDirectories | ForEach-Object { Get-ContainerPath $_ }
368388$ContainerSourceDir = Get-ContainerPath $SourceDirName
369389
390+ # Add both the unmapped (C:\X\...) and mapped (X:\...) paths to GitDirectories for safe.directory
391+ # Git may resolve paths differently depending on how it's invoked
392+ $expandedGitDirectories = @ ()
393+ foreach ($dir in $GitDirectories )
394+ {
395+ $expandedGitDirectories += $dir
396+ # If path is C:\<letter>\... (unmapped subst path), also add <letter>:\... (mapped path)
397+ if ($dir -match ' ^C:\\([A-Za-z])\\(.*)$' )
398+ {
399+ $letter = $Matches [1 ].ToUpper()
400+ $rest = $Matches [2 ]
401+ $expandedGitDirectories += " ${letter} :\$rest "
402+ }
403+ }
404+ $GitDirectories = $expandedGitDirectories
405+
370406# Build subst commands string for inline execution in docker run
371407$substCommandsInline = " "
372408foreach ($letter in $driveLetters.Keys | Sort-Object )
@@ -378,9 +414,34 @@ if ($driveLetters.Count -gt 0)
378414 Write-Host " Drive letter mappings for container: $ ( $driveLetters.Keys -join ' , ' ) " - ForegroundColor Cyan
379415}
380416
381- # Create empty Init.g.ps1 for Dockerfile COPY (required by Dockerfile but not used for drive mapping )
417+ # Create Init.g.ps1 with git configuration (safe.directory and user identity )
382418$initScript = Join-Path $dockerContextDirectory " Init.g.ps1"
383- " # Drive mappings are handled inline in docker run command" | Set-Content - Path $initScript - Encoding UTF8
419+ $initScriptContent = @"
420+ # Auto-generated initialization script for container startup
421+
422+ # Configure git user identity from Machine environment variables
423+ `$ gitUserName = [Environment]::GetEnvironmentVariable('GIT_USER_NAME', 'Machine')
424+ `$ gitUserEmail = [Environment]::GetEnvironmentVariable('GIT_USER_EMAIL', 'Machine')
425+ if (`$ gitUserName) {
426+ git config --global user.name `$ gitUserName
427+ }
428+ if (`$ gitUserEmail) {
429+ git config --global user.email `$ gitUserEmail
430+ }
431+
432+ # Configure git safe.directory for all mounted directories
433+ `$ gitDirectories = @(
434+ $ ( ($GitDirectories | ForEach-Object { " '$_ '" }) -join " ,`n " )
435+ )
436+
437+ foreach (`$ dir in `$ gitDirectories) {
438+ if (`$ dir) {
439+ `$ normalizedDir = (`$ dir -replace '\\\\', '/').TrimEnd('/') + '/'
440+ git config --global --add safe.directory `$ normalizedDir
441+ }
442+ }
443+ "@
444+ $initScriptContent | Set-Content - Path $initScript - Encoding UTF8
384445
385446$mountPointsAsString = $MountPoints -Join " ;"
386447$gitDirectoriesAsString = $GitDirectories -Join " ;"
@@ -410,7 +471,7 @@ if (-not $NoBuildImage)
410471 exit 1
411472 }
412473
413- Get-Content - Raw Dockerfile.claude | docker build - t $ImageTag -- build-arg GITDIRS = " $gitDirectoriesAsString " -- build-arg MOUNTPOINTS= " $mountPointsAsString " -f - $dockerContextDirectory
474+ Get-Content - Raw Dockerfile.claude | docker build - t $ImageTag -- build-arg MOUNTPOINTS= " $mountPointsAsString " -f - $dockerContextDirectory
414475 if ($LASTEXITCODE -ne 0 )
415476 {
416477 Write-Host " Docker build (Claude) failed with exit code $LASTEXITCODE " - ForegroundColor Red
@@ -421,7 +482,7 @@ if (-not $NoBuildImage)
421482 {
422483 # Build base image
423484 Write-Host " Building the base image with tag: $ImageTag " - ForegroundColor Green
424- Get-Content - Raw Dockerfile | docker build - t $ImageTag -- build-arg GITDIRS = " $gitDirectoriesAsString " -- build-arg MOUNTPOINTS= " $mountPointsAsString " -f - $dockerContextDirectory
485+ Get-Content - Raw Dockerfile | docker build - t $ImageTag -- build-arg MOUNTPOINTS= " $mountPointsAsString " -f - $dockerContextDirectory
425486 if ($LASTEXITCODE -ne 0 )
426487 {
427488 Write-Host " Docker build failed with exit code $LASTEXITCODE " - ForegroundColor Red
@@ -498,13 +559,13 @@ if (-not $BuildImage)
498559 {
499560 # Non-interactive mode with prompt - no -it flags
500561 $dockerArgs = @ ()
501- $inlineScript = " ${substCommandsInline}${copyClaudeJsonScript} cd '$SourceDirName '; & .\eng\RunClaude.g.ps1 -Prompt `" $ClaudePrompt `" "
562+ $inlineScript = " ${substCommandsInline} & c:\Init.g.ps1; ${copyClaudeJsonScript} cd '$SourceDirName '; & .\eng\RunClaude.g.ps1 -Prompt `" $ClaudePrompt `" "
502563 }
503564 else
504565 {
505566 # Interactive mode - requires TTY
506567 $dockerArgs = @ (" -it" )
507- $inlineScript = " ${substCommandsInline}${copyClaudeJsonScript} cd '$SourceDirName '; & .\eng\RunClaude.g.ps1"
568+ $inlineScript = " ${substCommandsInline} & c:\Init.g.ps1; ${copyClaudeJsonScript} cd '$SourceDirName '; & .\eng\RunClaude.g.ps1"
508569 }
509570
510571 $dockerArgsAsString = $dockerArgs -join " "
@@ -552,8 +613,8 @@ if (-not $BuildImage)
552613 $VolumeMappingsAsString = $VolumeMappings -join " "
553614 $dockerArgsAsString = $dockerArgs -join " "
554615
555- # Build inline script: subst drives, cd to source, run build
556- $inlineScript = " ${substCommandsInline} cd '$SourceDirName '; & .\$Script $buildArgsString ; $pwshExitCommand "
616+ # Build inline script: subst drives, run init, cd to source, run build
617+ $inlineScript = " ${substCommandsInline} & c:\Init.g.ps1; cd '$SourceDirName '; & .\$Script $buildArgsString ; $pwshExitCommand "
557618
558619 $pwshPath = ' C:\Program Files\PowerShell\7\pwsh.exe'
559620 Write-Host " Executing: `` docker run --rm --memory=12g $dockerArgsAsString $VolumeMappingsAsString -w $ContainerSourceDir $ImageTag `" $pwshPath `" $pwshArgs -Command `" $inlineScript `" " - ForegroundColor Cyan
0 commit comments