pr_reviewer/tools/git_tool.py
2026-05-08 23:46:17 +10:00

57 lines
2.2 KiB
Python

from pydantic import BaseModel, Field
from crewai_tools import BaseTool
import git
import os
import shutil
from typing import Type
class GitCloneInput(BaseModel):
"""Input schema for GitTool."""
repo_url: str = Field(..., description="URL of the Git repository to clone")
branch: str = Field(None, description="Branch to checkout (optional)")
commit: str = Field(None, description="Commit hash to checkout (optional)")
target_dir: str = Field(None, description="Target directory to clone into (optional)")
class GitTool(BaseTool):
name: str = "GitTool"
description: str = "Clones a Git repository and checks out a specific branch or commit"
args_schema: Type[BaseModel] = GitCloneInput
def _run(self, repo_url: str, branch: str = None, commit: str = None, target_dir: str = None) -> str:
"""
Clone a Git repository and checkout a specific branch or commit.
Args:
repo_url: URL of the Git repository to clone
branch: Branch to checkout (optional)
commit: Commit hash to checkout (optional)
target_dir: Target directory to clone into (optional)
Returns:
A message indicating the result of the operation.
"""
# If target_dir is not provided, extract the repository name from the URL
if target_dir is None:
target_dir = repo_url.split("/")[-1]
if target_dir.endswith(".git"):
target_dir = target_dir[:-4]
# Remove the target directory if it already exists to avoid conflicts
if os.path.exists(target_dir):
shutil.rmtree(target_dir)
try:
# Clone the repository
repo = git.Repo.clone_from(repo_url, target_dir)
# Checkout the specified branch or commit
if branch:
repo.git.checkout(branch)
elif commit:
repo.git.checkout(commit)
return f"Successfully cloned {repo_url} into {target_dir} and checked out {'branch: ' + branch if branch else 'commit: ' + commit if commit else 'default branch'}"
except Exception as e:
return f"Error cloning repository: {str(e)}"