Class: Ace::LLM::Providers::CLI::Atoms::WorktreeDirResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/llm/providers/cli/atoms/worktree_dir_resolver.rb

Overview

Detects if the current directory is a git worktree and returns the common git dir path that needs to be writable for sandbox tools.

In a worktree, ‘.git` is a file containing `gitdir: <path>` pointing to the worktree metadata under the parent repo’s ‘.git/worktrees/`. The parent `.git/` directory must be writable for index.lock etc.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.call(working_dir: Dir.pwd) ⇒ String?

Returns path to common .git dir, or nil if not a worktree.

Parameters:

  • working_dir (String) (defaults to: Dir.pwd)

    directory to check (default: Dir.pwd)

Returns:

  • (String, nil)

    path to common .git dir, or nil if not a worktree



17
18
19
# File 'lib/ace/llm/providers/cli/atoms/worktree_dir_resolver.rb', line 17

def self.call(working_dir: Dir.pwd)
  new.call(working_dir: working_dir)
end

Instance Method Details

#call(working_dir: Dir.pwd) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ace/llm/providers/cli/atoms/worktree_dir_resolver.rb', line 21

def call(working_dir: Dir.pwd)
  dot_git = File.join(working_dir, ".git")

  # If .git is a directory (normal repo) or doesn't exist, not a worktree
  return nil unless File.file?(dot_git)

  content = File.read(dot_git).strip
  return nil unless content.start_with?("gitdir:")

  gitdir = content.sub(/\Agitdir:\s*/, "")

  # Resolve relative paths against working_dir
  gitdir = File.expand_path(gitdir, working_dir) unless gitdir.start_with?("/")

  # Walk up from gitdir to find the common .git/ directory
  # Typical path: /repo/.git/worktrees/<name> → we want /repo/.git
  path = gitdir
  while path != "/" && path != "."
    basename = File.basename(path)
    parent = File.dirname(path)

    if basename == "worktrees" && File.directory?(File.join(parent, "refs"))
      return parent
    end

    path = parent
  end

  nil
end