fix: mount git worktree metadata directory into container
Git worktrees store their metadata in the parent repository's
.git/worktrees/{name} directory. The worktree's .git file contains
an absolute path to this directory.
When mounting a worktree into a container, git commands fail because
the .git file references a host path that doesn't exist in the container.
This fix mounts the git worktree metadata directory into the container
at the same path it exists on the host, so git commands work correctly.
This commit is contained in:
@@ -302,6 +302,7 @@ func (m *Manager) Launch(ctx context.Context, req *LaunchRequest) (*AgentInstanc
|
||||
|
||||
// 3. Handle worktree creation/reuse if enabled
|
||||
workspacePath := req.WorkspacePath
|
||||
var gitWorktreeMetadataPath string // Path to git worktree metadata for container mount
|
||||
if req.UseWorktree && m.worktreeMgr != nil && req.RepositoryPath != "" {
|
||||
wt, err := m.getOrCreateWorktree(ctx, req)
|
||||
if err != nil {
|
||||
@@ -311,9 +312,13 @@ func (m *Manager) Launch(ctx context.Context, req *LaunchRequest) (*AgentInstanc
|
||||
// Fall back to direct mount if worktree creation fails
|
||||
} else {
|
||||
workspacePath = wt.Path
|
||||
// Git worktrees store metadata in the main repo's .git/worktrees/{name} directory
|
||||
// We need to mount this into the container at the same path for git commands to work
|
||||
gitWorktreeMetadataPath = filepath.Join(req.RepositoryPath, ".git", "worktrees", req.TaskID)
|
||||
m.logger.Info("using worktree for agent",
|
||||
zap.String("task_id", req.TaskID),
|
||||
zap.String("worktree_path", workspacePath),
|
||||
zap.String("git_metadata_path", gitWorktreeMetadataPath),
|
||||
zap.String("branch", wt.Branch))
|
||||
}
|
||||
}
|
||||
@@ -324,7 +329,7 @@ func (m *Manager) Launch(ctx context.Context, req *LaunchRequest) (*AgentInstanc
|
||||
// 5. Build container config from registry config (use worktree path if available)
|
||||
reqWithWorktree := *req
|
||||
reqWithWorktree.WorkspacePath = workspacePath
|
||||
containerConfig := m.buildContainerConfig(instanceID, &reqWithWorktree, agentConfig)
|
||||
containerConfig := m.buildContainerConfig(instanceID, &reqWithWorktree, agentConfig, gitWorktreeMetadataPath)
|
||||
|
||||
// 6. Create and start the container
|
||||
containerID, err := m.docker.CreateContainer(ctx, containerConfig)
|
||||
@@ -1020,7 +1025,9 @@ func (m *Manager) updateInstanceError(instanceID, errorMsg string) {
|
||||
}
|
||||
|
||||
// buildContainerConfig builds a Docker container config from agent registry config
|
||||
func (m *Manager) buildContainerConfig(instanceID string, req *LaunchRequest, agentConfig *registry.AgentTypeConfig) docker.ContainerConfig {
|
||||
// gitWorktreeMetadataPath is the host path to the git worktree metadata (e.g., /path/to/repo/.git/worktrees/{task_id})
|
||||
// If non-empty, it will be mounted into the container at the same path so git commands work correctly
|
||||
func (m *Manager) buildContainerConfig(instanceID string, req *LaunchRequest, agentConfig *registry.AgentTypeConfig, gitWorktreeMetadataPath string) docker.ContainerConfig {
|
||||
// Build image name with tag
|
||||
imageName := agentConfig.Image
|
||||
if agentConfig.Tag != "" {
|
||||
@@ -1044,6 +1051,19 @@ func (m *Manager) buildContainerConfig(instanceID string, req *LaunchRequest, ag
|
||||
})
|
||||
}
|
||||
|
||||
// Add git worktree metadata mount if using a worktree
|
||||
// Git worktrees reference the parent repo's .git/worktrees/{name} directory via the .git file
|
||||
// We need to mount this directory into the container at the same host path for git to work
|
||||
if gitWorktreeMetadataPath != "" {
|
||||
mounts = append(mounts, docker.MountConfig{
|
||||
Source: gitWorktreeMetadataPath,
|
||||
Target: gitWorktreeMetadataPath, // Same path inside container
|
||||
ReadOnly: false,
|
||||
})
|
||||
m.logger.Debug("added git worktree metadata mount",
|
||||
zap.String("path", gitWorktreeMetadataPath))
|
||||
}
|
||||
|
||||
// Merge environment variables
|
||||
env := make([]string, 0)
|
||||
// Add default env from agent config
|
||||
|
||||
Reference in New Issue
Block a user