Skip to content

Worktree

worktree

GitWorktreeTool — add, remove, and list git worktrees.

GitWorktreeTool

Bases: AXMTool

Add, remove, or list git worktrees.

Registered as git_worktree via axm.tools entry point.

Source code in packages/axm-git/src/axm_git/tools/worktree.py
class GitWorktreeTool(AXMTool):
    """Add, remove, or list git worktrees.

    Registered as ``git_worktree`` via axm.tools entry point.
    """

    @property
    def name(self) -> str:
        """Tool name used for MCP registration."""
        return "git_worktree"

    def execute(  # type: ignore[override]
        self,
        *,
        action: str,
        path: str = ".",
        branch: str | None = None,
        base: str = "main",
        force: bool = False,
        **kwargs: Any,
    ) -> ToolResult:
        """Manage git worktrees.

        Args:
            action: One of ``add``, ``remove``, ``list``.
            path: For ``add``/``remove``: worktree path.
                  For ``list``: repository path.
            branch: Branch name for ``add`` action.
            base: Base ref for ``add`` (default ``main``).
            force: Force removal for ``remove`` action.

        Returns:
            ToolResult with worktree data on success.
        """
        resolved = Path(path).resolve()

        match action:
            case "list":
                return self._list(resolved)
            case "add":
                return self._add(
                    resolved,
                    branch=branch,
                    base=base,
                )
            case "remove":
                return self._remove(resolved, force=force)
            case _:
                return ToolResult(
                    success=False,
                    error=(
                        f"Invalid action {action!r}. Use 'add', 'remove', or 'list'."
                    ),
                )

    def _list(self, path: Path) -> ToolResult:
        """List all worktrees."""
        git_root = find_git_root(path)
        if git_root is None:
            return not_a_repo_error("not a git repository", path)

        result = run_git(["worktree", "list", "--porcelain"], git_root)
        if result.returncode != 0:
            return ToolResult(
                success=False,
                error=result.stderr.strip() or result.stdout.strip(),
            )

        worktrees = _parse_worktree_porcelain(result.stdout)
        return ToolResult(
            success=True,
            data={"worktrees": worktrees},
        )

    def _add(
        self,
        path: Path,
        *,
        branch: str | None,
        base: str,
    ) -> ToolResult:
        """Add a new worktree."""
        git_root = find_git_root(path)
        if git_root is None:
            return not_a_repo_error("not a git repository", path)

        cmd: list[str] = ["worktree", "add"]
        if branch:
            cmd.extend(["-b", branch])
        cmd.append(str(path))
        cmd.append(base)

        result = run_git(cmd, git_root)
        if result.returncode != 0:
            return ToolResult(
                success=False,
                error=result.stderr.strip() or result.stdout.strip(),
            )

        return ToolResult(
            success=True,
            data={
                "path": str(path),
                "branch": branch or base,
                "base": base,
            },
        )

    def _remove(self, path: Path, *, force: bool) -> ToolResult:
        """Remove an existing worktree."""
        git_root = find_git_root(path)
        if git_root is None:
            return not_a_repo_error("not a git repository", path)

        cmd: list[str] = ["worktree", "remove", str(path)]
        if force:
            cmd.append("--force")

        result = run_git(cmd, git_root)
        if result.returncode != 0:
            return ToolResult(
                success=False,
                error=result.stderr.strip() or result.stdout.strip(),
            )

        return ToolResult(
            success=True,
            data={"removed": str(path)},
        )
name property

Tool name used for MCP registration.

execute(*, action, path='.', branch=None, base='main', force=False, **kwargs)

Manage git worktrees.

Parameters:

Name Type Description Default
action str

One of add, remove, list.

required
path str

For add/remove: worktree path. For list: repository path.

'.'
branch str | None

Branch name for add action.

None
base str

Base ref for add (default main).

'main'
force bool

Force removal for remove action.

False

Returns:

Type Description
ToolResult

ToolResult with worktree data on success.

Source code in packages/axm-git/src/axm_git/tools/worktree.py
def execute(  # type: ignore[override]
    self,
    *,
    action: str,
    path: str = ".",
    branch: str | None = None,
    base: str = "main",
    force: bool = False,
    **kwargs: Any,
) -> ToolResult:
    """Manage git worktrees.

    Args:
        action: One of ``add``, ``remove``, ``list``.
        path: For ``add``/``remove``: worktree path.
              For ``list``: repository path.
        branch: Branch name for ``add`` action.
        base: Base ref for ``add`` (default ``main``).
        force: Force removal for ``remove`` action.

    Returns:
        ToolResult with worktree data on success.
    """
    resolved = Path(path).resolve()

    match action:
        case "list":
            return self._list(resolved)
        case "add":
            return self._add(
                resolved,
                branch=branch,
                base=base,
            )
        case "remove":
            return self._remove(resolved, force=force)
        case _:
            return ToolResult(
                success=False,
                error=(
                    f"Invalid action {action!r}. Use 'add', 'remove', or 'list'."
                ),
            )