Class: Aidp::WorktreeBranchManager
- Inherits:
-
Object
- Object
- Aidp::WorktreeBranchManager
- Defined in:
- lib/aidp/worktree_branch_manager.rb
Overview
Manages git worktrees for pull request branches
Defined Under Namespace
Classes: WorktreeCreationError, WorktreeLookupError
Instance Method Summary collapse
-
#create_worktree(branch:, base_branch: "main") ⇒ Object
Create a new worktree for a branch.
-
#find_or_create_pr_worktree(pr_number:, head_branch:, base_branch: "main") ⇒ Object
Find or create a worktree for a PR, with advanced lookup strategies.
-
#find_worktree(branch:) ⇒ Object
Find an existing worktree for a given branch or PR.
-
#initialize(project_dir:, logger: Aidp.logger) ⇒ WorktreeBranchManager
constructor
Initialize with a project directory and optional logger.
Constructor Details
#initialize(project_dir:, logger: Aidp.logger) ⇒ WorktreeBranchManager
Initialize with a project directory and optional logger
11 12 13 14 15 16 |
# File 'lib/aidp/worktree_branch_manager.rb', line 11 def initialize(project_dir:, logger: Aidp.logger) @project_dir = project_dir @logger = logger @worktree_registry_path = File.join(project_dir, ".aidp", "worktrees.json") @pr_worktree_registry_path = File.join(project_dir, ".aidp", "pr_worktrees.json") end |
Instance Method Details
#create_worktree(branch:, base_branch: "main") ⇒ Object
Create a new worktree for a branch
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/aidp/worktree_branch_manager.rb', line 79 def create_worktree(branch:, base_branch: "main") Aidp.log_debug("worktree_branch_manager", "creating_worktree", branch: branch, base_branch: base_branch) # Validate branch name to prevent path traversal validate_branch_name!(branch) # Check if worktree already exists existing_worktree = find_worktree(branch: branch) return existing_worktree if existing_worktree # Ensure base branch exists base_ref = (branch == "main") ? "main" : "refs/heads/#{base_branch}" base_exists_cmd = "git show-ref --verify --quiet #{base_ref}" system({"GIT_DIR" => File.join(@project_dir, ".git")}, "cd #{@project_dir} && #{base_exists_cmd}") # If base branch doesn't exist locally, create it unless $?.success? system({"GIT_DIR" => File.join(@project_dir, ".git")}, "cd #{@project_dir} && git checkout -b #{base_branch}") end # Create worktree directory worktree_name = branch.tr("/", "_") worktree_path = File.join(@project_dir, ".worktrees", worktree_name) # Ensure .worktrees directory exists FileUtils.mkdir_p(File.join(@project_dir, ".worktrees")) # Create the worktree cmd = "git worktree add -b #{branch} #{worktree_path} #{base_branch}" result = system({"GIT_DIR" => File.join(@project_dir, ".git")}, "cd #{@project_dir} && #{cmd}") unless result Aidp.log_error("worktree_branch_manager", "worktree_creation_failed", branch: branch, base_branch: base_branch) raise WorktreeCreationError, "Failed to create worktree for branch #{branch}" end # Update registry update_registry(branch, worktree_path) worktree_path end |
#find_or_create_pr_worktree(pr_number:, head_branch:, base_branch: "main") ⇒ Object
Find or create a worktree for a PR, with advanced lookup strategies
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/aidp/worktree_branch_manager.rb', line 47 def find_or_create_pr_worktree(pr_number:, head_branch:, base_branch: "main") Aidp.log_debug("worktree_branch_manager", "finding_or_creating_pr_worktree", pr_number: pr_number, head_branch: head_branch, base_branch: base_branch) # First, check the PR-specific registry pr_registry = read_pr_registry pr_worktree = pr_registry.find { |w| w["pr_number"] == pr_number } # If a valid worktree exists in the registry, return it if pr_worktree worktree_path = pr_worktree["path"] return worktree_path if File.directory?(worktree_path) end # Attempt to find worktree by branch name existing_worktree = find_worktree(branch: head_branch) return existing_worktree if existing_worktree # If no existing worktree, create a new one worktree_path = create_worktree(branch: head_branch, base_branch: base_branch) # Update PR-specific registry update_pr_registry(pr_number, head_branch, worktree_path, base_branch) worktree_path rescue => e Aidp.log_error("worktree_branch_manager", "pr_worktree_creation_failed", error: e., pr_number: pr_number, head_branch: head_branch) raise end |
#find_worktree(branch:) ⇒ Object
Find an existing worktree for a given branch or PR
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/aidp/worktree_branch_manager.rb', line 19 def find_worktree(branch:) Aidp.log_debug("worktree_branch_manager", "finding_worktree", branch: branch) raise WorktreeLookupError, "Invalid git repository: #{@project_dir}" unless git_repository? # First, check registry first for exact branch match worktree_info = read_registry.find { |w| w["branch"] == branch } if worktree_info worktree_path = worktree_info["path"] return worktree_path if File.directory?(worktree_path) end # Fallback: Use git worktree list to find the worktree worktree_list_output = run_git_command("git worktree list") worktree_list_output.split("\n").each do |line| path, branch_info = line.split(" ", 2) return path if branch_info&.include?(branch) end nil rescue => e Aidp.log_error("worktree_branch_manager", "worktree_lookup_failed", error: e., branch: branch) raise end |