angreal.integrations.git
Git repository operations and version control automation.
Overview
Section titled “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
Section titled “Prerequisites”Git must be installed and available in your system PATH. The integration does not bundle Git itself.
Functions
Section titled “Functions”Clone a Git repository to a local destination.
from angreal.integrations.git import clone
destination = clone(remote, destination=None)Parameters:
remote(str): The URL or path of the repository to clonedestination(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 directorypath = clone("https://github.com/user/project.git")print(f"Cloned to: {path}")
# Clone to specific directorypath = clone("https://github.com/user/project.git", "my-local-copy")Classes
Section titled “Classes”A wrapper around Git operations for a specific working directory.
from angreal.integrations.git import Git
git = Git(working_dir=None)Constructor
Section titled “Constructor”Git(working_dir=None)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
Section titled “Properties”working_dir
Section titled “working_dir”Get the working directory path.
@propertydef working_dir(self) -> strReturns:
str: The absolute path to the working directory
Instance Methods
Section titled “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 outputstdout(bytes): Standard output
Initialize a new Git repository.
def init(self, bare=None) -> tuple[int, bytes, bytes]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")Stage files for commit.
def add(self, *paths) -> tuple[int, bytes, bytes]Parameters:
*paths: Variable number of file paths to stage
Example:
# Stage specific filesgit.add("README.md", "setup.py")
# Stage all changesgit.add(".")commit
Section titled “commit”Create a commit with the staged changes.
def commit(self, message, all=None) -> tuple[int, bytes, bytes]Parameters:
message(str): The commit messageall(bool, optional): Stage all modified files before committing (equivalent togit commit -a). Defaults to False.
Example:
# Standard commitgit.add(".")exit_code, stderr, stdout = git.commit("Add new feature")
# Commit all modified files in one stepgit.commit("Quick fix", all=True)Push commits to a remote repository.
def push(self, remote=None, branch=None) -> tuple[int, bytes, bytes]Parameters:
remote(str, optional): Remote name (e.g., “origin”)branch(str, optional): Branch name to push
Example:
# Push to default remote and branchgit.push()
# Push to specific remote and branchgit.push("origin", "main")
# Push current branch to origingit.push("origin")Pull changes from a remote repository.
def pull(self, remote=None, branch=None) -> tuple[int, bytes, bytes]Parameters:
remote(str, optional): Remote namebranch(str, optional): Branch name to pull
Example:
# Pull from default remotegit.pull()
# Pull specific branchgit.pull("origin", "develop")status
Section titled “status”Get the working tree status.
def status(self, short=None) -> tuple[int, bytes, bytes]Parameters:
short(bool, optional): Use short format output. Defaults to False.
Example:
exit_code, stderr, stdout = git.status()print(stdout.decode())
# Short formatexit_code, stderr, stdout = git.status(short=True)branch
Section titled “branch”List or create branches.
def branch(self, name=None, delete=None) -> tuple[int, bytes, bytes]Parameters:
name(str, optional): Branch name to create or deletedelete(bool, optional): Delete the specified branch. Defaults to False.
Example:
# List all branchesexit_code, stderr, stdout = git.branch()print(stdout.decode())
# Create a new branchgit.branch("feature-xyz")
# Delete a branchgit.branch("old-feature", delete=True)checkout
Section titled “checkout”Switch branches or restore working tree files.
def checkout(self, branch, create=None) -> tuple[int, bytes, bytes]Parameters:
branch(str): Branch name to switch tocreate(bool, optional): Create the branch if it doesn’t exist (equivalent togit checkout -b). Defaults to False.
Example:
# Switch to existing branchgit.checkout("develop")
# Create and switch to new branchgit.checkout("new-feature", create=True)Create or list tags.
def tag(self, name, message=None) -> tuple[int, bytes, bytes]Parameters:
name(str): Tag namemessage(str, optional): Tag message for annotated tags
Example:
# Create lightweight taggit.tag("v1.0.0")
# Create annotated taggit.tag("v2.0.0", message="Release version 2.0.0")execute
Section titled “execute”Execute an arbitrary Git subcommand.
def execute(self, subcommand, args) -> tuple[int, bytes, bytes]Parameters:
subcommand(str): The Git subcommand (e.g., “log”, “diff”, “stash”)args(List[str]): Arguments for the subcommand
Example:
# View commit logexit_code, stderr, stdout = git.execute("log", ["--oneline", "-5"])print(stdout.decode())
# Show diffexit_code, stderr, stdout = git.execute("diff", ["HEAD~1"])
# Stash changesgit.execute("stash", ["push", "-m", "Work in progress"])Callable Interface
Section titled “Callable Interface”The Git class supports a callable interface for executing commands with keyword arguments.
git(command, *args, **kwargs) -> tuple[int, bytes, bytes]Example:
# These are equivalentgit.execute("log", ["--oneline"])git("log", "--oneline")
# With keyword arguments (converted to flags)git("commit", "-m", "Message", amend=True)GitException
Section titled “GitException”Exception raised for Git-related errors.
from angreal.integrations.git import GitExceptionThis exception is raised when attempting to call an unsupported Git command through attribute access.
Examples
Section titled “Examples”Basic Repository Workflow
Section titled “Basic Repository Workflow”from angreal.integrations.git import Git, clone
# Clone a repositorypath = clone("https://github.com/user/project.git", "local-project")
# Work with the repositorygit = Git(path)
# Make changes and commitgit.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
Section titled “Feature Branch Workflow”from angreal.integrations.git import Git
git = Git("/path/to/repo")
# Create and switch to feature branchgit.checkout("feature/new-api", create=True)
# Make changesgit.add(".")git.commit("Implement new API endpoint")
# Push feature branchgit.push("origin", "feature/new-api")Release Tagging
Section titled “Release Tagging”from angreal.integrations.git import Gitimport 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
Section titled “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
Section titled “Custom Git Commands”from angreal.integrations.git import Git
git = Git(".")
# View recent commitsexit_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 commitgit.execute("cherry-pick", ["abc123"])Error Handling
Section titled “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
Section titled “See Also”- Docker Compose Integration - Container orchestration
- Virtual Environment Integration - Python environment management
- Flox Integration - Cross-language environment management