repomind / tools /git_log.py
ZeroR3's picture
REPOMIND v0.1 — repo-scale coding agent demo
e3a472a
"""git_log tool — read-only commit history queries."""
from __future__ import annotations
import subprocess
from pathlib import Path
from .base import ToolResult, ToolSpec
def make_tool(repo_root: str | Path, max_commits: int = 50) -> ToolSpec:
root = Path(repo_root).resolve()
def run(path: str = "", limit: int = 20, since: str = "") -> ToolResult:
if not (root / ".git").exists():
return ToolResult(ok=False, output="", error="not a git repository")
n = max(1, min(limit, max_commits))
cmd = ["git", "log", f"-n{n}", "--pretty=format:%h|%an|%ai|%s"]
if since:
cmd += [f"--since={since}"]
if path:
cmd += ["--", path]
try:
proc = subprocess.run(cmd, cwd=str(root), capture_output=True, text=True, timeout=30)
except subprocess.TimeoutExpired:
return ToolResult(ok=False, output="", error="git log timeout")
if proc.returncode != 0:
return ToolResult(ok=False, output="", error=proc.stderr.strip())
rows = [_format_row(line) for line in proc.stdout.splitlines() if line]
return ToolResult(ok=True, output="\n".join(rows), extra={"commits": len(rows)})
return ToolSpec(
name="git_log",
description="Read commit history. Optionally filter by path or --since.",
parameters={
"type": "object",
"properties": {
"path": {"type": "string", "default": ""},
"limit": {"type": "integer", "default": 20},
"since": {"type": "string", "default": "", "description": "git --since (e.g. '2 weeks ago')"},
},
},
runner=run,
)
def _format_row(line: str) -> str:
parts = line.split("|", 3)
if len(parts) != 4:
return line
sha, author, date, subject = parts
return f"{sha[:9]} {date[:10]} {author[:24]:<24} {subject}"