Files
ClaudeInit/myclaude/git_ops.py
T
2026-04-13 22:04:05 +02:00

60 lines
1.7 KiB
Python

"""Git operations for myclaude using GitPython."""
import shutil
import tempfile
from contextlib import contextmanager
from pathlib import Path
from typing import Generator
from git import GitCommandError, Repo
@contextmanager
def temp_clone(repo_url: str, keep: bool = False) -> Generator[tuple[Path, Repo], None, None]:
"""Clone a git repository into a temporary directory.
The temporary directory is automatically cleaned up on exit unless
keep is True, in which case it is preserved for inspection.
Args:
repo_url: The SSH URL of the repository to clone.
keep: If True, the temporary directory is not deleted after use.
Yields:
A tuple of (path to the cloned repo, Repo object).
Raises:
RuntimeError: If the clone operation fails.
"""
tmp_dir = tempfile.mkdtemp()
try:
try:
repo = Repo.clone_from(repo_url, tmp_dir)
except GitCommandError as e:
raise RuntimeError(
f"Failed to clone repository '{repo_url}': {e}"
) from e
yield Path(tmp_dir), repo
finally:
if keep:
print(f"[debug] Temporary directory kept at: {tmp_dir}")
else:
shutil.rmtree(tmp_dir, ignore_errors=True)
def commit_and_push(repo: Repo, message: str) -> None:
"""Stage all changes, commit, and push to the remote origin.
Args:
repo: A GitPython Repo object with an 'origin' remote configured.
message: The commit message.
Raises:
RuntimeError: If there are no changes to commit.
"""
repo.git.add(A=True)
if not repo.is_dirty(index=True, working_tree=False):
raise RuntimeError("Nothing to commit: no changes detected.")
repo.index.commit(message)
repo.remotes.origin.push()