angreal.integrations.git¶
Git repository operations and version control automation.
Overview¶
Angreal's Git integration provides a Python interface for common Git operations. The module wraps the Git command-line tool, offering both convenience methods for common operations and a flexible escape hatch for arbitrary Git commands.
The integration returns structured output with exit codes, stdout, and stderr, making it straightforward to handle both successful operations and error conditions in your automation scripts.
Prerequisites¶
Git must be installed and available in your system PATH. The integration does not bundle Git itself.
Functions¶
clone¶
Clone a Git repository to a local destination.
Parameters:
- remote (str): The URL or path of the repository to clone
- destination (str, optional): Local path for the cloned repository. If not specified, Git will use the repository name.
Returns:
- str: The absolute path to the cloned repository
Example:
from angreal.integrations.git import clone
# Clone to auto-named directory
path = clone("https://github.com/user/project.git")
print(f"Cloned to: {path}")
# Clone to specific directory
path = clone("https://github.com/user/project.git", "my-local-copy")
Classes¶
Git¶
A wrapper around Git operations for a specific working directory.
Constructor¶
Parameters:
- working_dir (str, optional): Path to the Git repository. Defaults to the current working directory.
Raises:
- RuntimeError: If the specified directory does not exist
Properties¶
working_dir¶
Get the working directory path.
Returns:
- str: The absolute path to the working directory
Instance Methods¶
All Git methods return a tuple of (exit_code, stderr, stdout) where:
- exit_code (int): The command exit code (0 indicates success)
- stderr (bytes): Standard error output
- stdout (bytes): Standard output
init¶
Initialize a new Git repository.
Parameters:
- bare (bool, optional): Create a bare repository. Defaults to False.
Example:
git = Git("/path/to/new/project")
exit_code, stderr, stdout = git.init()
if exit_code == 0:
print("Repository initialized")
add¶
Stage files for commit.
Parameters:
- *paths: Variable number of file paths to stage
Example:
commit¶
Create a commit with the staged changes.
Parameters:
- message (str): The commit message
- all (bool, optional): Stage all modified files before committing (equivalent to git commit -a). Defaults to False.
Example:
# Standard commit
git.add(".")
exit_code, stderr, stdout = git.commit("Add new feature")
# Commit all modified files in one step
git.commit("Quick fix", all=True)
push¶
Push commits to a remote repository.
Parameters:
- remote (str, optional): Remote name (e.g., "origin")
- branch (str, optional): Branch name to push
Example:
# Push to default remote and branch
git.push()
# Push to specific remote and branch
git.push("origin", "main")
# Push current branch to origin
git.push("origin")
pull¶
Pull changes from a remote repository.
Parameters:
- remote (str, optional): Remote name
- branch (str, optional): Branch name to pull
Example:
status¶
Get the working tree status.
Parameters:
- short (bool, optional): Use short format output. Defaults to False.
Example:
exit_code, stderr, stdout = git.status()
print(stdout.decode())
# Short format
exit_code, stderr, stdout = git.status(short=True)
branch¶
List or create branches.
Parameters:
- name (str, optional): Branch name to create or delete
- delete (bool, optional): Delete the specified branch. Defaults to False.
Example:
# List all branches
exit_code, stderr, stdout = git.branch()
print(stdout.decode())
# Create a new branch
git.branch("feature-xyz")
# Delete a branch
git.branch("old-feature", delete=True)
checkout¶
Switch branches or restore working tree files.
Parameters:
- branch (str): Branch name to switch to
- create (bool, optional): Create the branch if it doesn't exist (equivalent to git checkout -b). Defaults to False.
Example:
# Switch to existing branch
git.checkout("develop")
# Create and switch to new branch
git.checkout("new-feature", create=True)
tag¶
Create or list tags.
Parameters:
- name (str): Tag name
- message (str, optional): Tag message for annotated tags
Example:
# Create lightweight tag
git.tag("v1.0.0")
# Create annotated tag
git.tag("v2.0.0", message="Release version 2.0.0")
execute¶
Execute an arbitrary Git subcommand.
Parameters:
- subcommand (str): The Git subcommand (e.g., "log", "diff", "stash")
- args (List[str]): Arguments for the subcommand
Example:
# View commit log
exit_code, stderr, stdout = git.execute("log", ["--oneline", "-5"])
print(stdout.decode())
# Show diff
exit_code, stderr, stdout = git.execute("diff", ["HEAD~1"])
# Stash changes
git.execute("stash", ["push", "-m", "Work in progress"])
Callable Interface¶
The Git class supports a callable interface for executing commands with keyword arguments.
Example:
# These are equivalent
git.execute("log", ["--oneline"])
git("log", "--oneline")
# With keyword arguments (converted to flags)
git("commit", "-m", "Message", amend=True)
GitException¶
Exception raised for Git-related errors.
This exception is raised when attempting to call an unsupported Git command through attribute access.
Examples¶
Basic Repository Workflow¶
from angreal.integrations.git import Git, clone
# Clone a repository
path = clone("https://github.com/user/project.git", "local-project")
# Work with the repository
git = Git(path)
# Make changes and commit
git.add("README.md")
exit_code, stderr, stdout = git.commit("Update documentation")
if exit_code == 0:
print("Commit successful")
git.push("origin", "main")
else:
print(f"Commit failed: {stderr.decode()}")
Feature Branch Workflow¶
from angreal.integrations.git import Git
git = Git("/path/to/repo")
# Create and switch to feature branch
git.checkout("feature/new-api", create=True)
# Make changes
git.add(".")
git.commit("Implement new API endpoint")
# Push feature branch
git.push("origin", "feature/new-api")
Release Tagging¶
from angreal.integrations.git import Git
import angreal
@angreal.command(name="release", about="Create a release tag")
@angreal.argument("version", help="Version number (e.g., 1.2.3)")
def release(version):
"""Tag the current commit as a release."""
git = Git(".")
tag_name = f"v{version}"
message = f"Release version {version}"
exit_code, stderr, stdout = git.tag(tag_name, message=message)
if exit_code == 0:
print(f"Created tag {tag_name}")
git.push("origin", tag_name)
else:
print(f"Failed to create tag: {stderr.decode()}")
Status Checking¶
from angreal.integrations.git import Git
def check_repo_status():
"""Check and report repository status."""
git = Git(".")
exit_code, stderr, stdout = git.status(short=True)
status_output = stdout.decode().strip()
if not status_output:
print("Working tree is clean")
else:
print("Pending changes:")
print(status_output)
Custom Git Commands¶
from angreal.integrations.git import Git
git = Git(".")
# View recent commits
exit_code, stderr, stdout = git.execute("log", [
"--oneline",
"--graph",
"--decorate",
"-10"
])
print(stdout.decode())
# Interactive rebase (non-interactive version)
git.execute("rebase", ["--onto", "main", "feature-old", "feature-new"])
# Cherry-pick a commit
git.execute("cherry-pick", ["abc123"])
Error Handling¶
All Git operations return an exit code as the first element of the tuple. A non-zero exit code indicates an error occurred.
from angreal.integrations.git import Git
git = Git(".")
exit_code, stderr, stdout = git.push("origin", "main")
if exit_code != 0:
error_message = stderr.decode()
if "rejected" in error_message:
print("Push rejected - pull changes first")
elif "Authentication" in error_message:
print("Authentication failed - check credentials")
else:
print(f"Push failed: {error_message}")
See Also¶
- Docker Compose Integration - Container orchestration
- Virtual Environment Integration - Python environment management
- Flox Integration - Cross-language environment management