Expand description
Git operations wrapper for AGPM
This module provides a safe, async wrapper around the system git
command, serving as
the foundation for AGPM’s distributed package management capabilities. Unlike libraries
that use embedded Git implementations (like libgit2
), this module leverages the system’s
installed Git binary to ensure maximum compatibility with existing Git configurations,
authentication methods, and platform-specific optimizations.
§Design Philosophy: CLI-Based Git Integration
AGPM follows the same approach as Cargo with git-fetch-with-cli
, using the system’s
git
command rather than an embedded Git library. This design choice provides several
critical advantages:
- Authentication Compatibility: Seamlessly works with SSH agents, credential helpers, Git configuration, and platform-specific authentication (Windows Credential Manager, macOS Keychain, Linux credential stores)
- Feature Completeness: Access to all Git features without library limitations
- Platform Integration: Leverages platform-optimized Git builds and configurations
- Security: Benefits from system Git’s security updates and hardening
- Debugging: Uses familiar Git commands for troubleshooting and logging
§Core Features
§Asynchronous Operations
All Git operations are async and built on Tokio, enabling:
- Non-blocking I/O for better performance
- Concurrent repository operations
- Progress reporting during long operations
- Graceful cancellation support
§Worktree Support for Parallel Operations
Advanced Git worktree integration for safe parallel package installation:
- Bare repository cloning: Creates repositories optimized for worktrees
- Parallel worktree creation: Multiple versions checked out simultaneously
- Per-worktree locking: Individual worktree creation locks prevent conflicts
- Command-level concurrency: Parallelism controlled by
--max-parallel
flag - Automatic cleanup: Efficient worktree lifecycle management
- Conflict-free operations: Each dependency gets its own isolated working directory
§Progress Reporting
User feedback during:
- Repository cloning with transfer progress
- Fetch operations with network activity
- Large repository operations
§Authentication Handling
Supports multiple authentication methods through URL-based configuration:
- HTTPS with embedded tokens:
https://token@github.com/user/repo.git
- SSH with key-based authentication:
git@github.com:user/repo.git
- System credential helpers and Git configuration
- Platform-specific credential storage
§Cross-Platform Compatibility
Tested and optimized for:
- Windows: Handles path length limits,
PowerShell
vs CMD differences - macOS: Integrates with Keychain and Xcode command line tools
- Linux: Works with various distributions and Git installations
§Security Considerations
§Command Injection Prevention
All Git operations use proper argument passing to prevent injection attacks:
- Arguments passed as separate parameters, not shell strings
- URL validation before Git operations
- Path sanitization for repository locations
§Authentication Security
- Credentials never logged or exposed in error messages
- Authentication URLs are stripped from public error output
- Supports secure credential storage via system Git configuration
§Network Security
- HTTPS verification enabled by default
- Support for custom CA certificates via Git configuration
- Timeout handling for network operations
§Performance Characteristics
§Network Operations
- Async I/O prevents blocking during network operations
- Parallel fetch operations for multiple repositories
- Efficient progress reporting without polling
§Local Operations
- Direct file system access for repository validation
- Optimized branch/tag listing with minimal Git calls
- Efficient checkout operations with proper reset handling
§Error Handling Strategy
The module provides rich error context through AgpmError
variants:
- Network failures with retry suggestions
- Authentication errors with configuration guidance
- Repository format errors with recovery steps
- Platform-specific error translation
§Usage Examples
§Basic Repository Operations
use agpm_cli::git::GitRepo;
use std::env;
// Use platform-appropriate temp directory
let temp_dir = env::temp_dir();
let repo_path = temp_dir.join("repo");
// Clone a repository
let repo = GitRepo::clone(
"https://github.com/example/repo.git",
&repo_path
).await?;
// Fetch updates from remote
repo.fetch(None).await?;
// Checkout a specific version
repo.checkout("v1.2.3").await?;
// List available tags
let tags = repo.list_tags().await?;
println!("Available versions: {:?}", tags);
§Authentication with URLs
use agpm_cli::git::GitRepo;
use std::env;
// Use platform-appropriate temp directory
let temp_dir = env::temp_dir();
let repo_path = temp_dir.join("private-repo");
// Clone with authentication embedded in URL
let repo = GitRepo::clone(
"https://token:ghp_xxxx@github.com/private/repo.git",
&repo_path
).await?;
// Fetch with different authentication URL
let auth_url = "https://oauth2:token@github.com/private/repo.git";
repo.fetch(Some(auth_url)).await?;
§Repository Validation
use agpm_cli::git::{GitRepo, ensure_git_available, is_valid_git_repo};
use std::env;
// Ensure Git is installed
ensure_git_available()?;
// Verify repository URL before cloning
GitRepo::verify_url("https://github.com/example/repo.git").await?;
// Check if directory is a valid Git repository
let temp_dir = env::temp_dir();
let path = temp_dir.join("repo");
if is_valid_git_repo(&path) {
let repo = GitRepo::new(&path);
let url = repo.get_remote_url().await?;
println!("Repository URL: {}", url);
}
§Worktree-based Parallel Operations
use agpm_cli::git::GitRepo;
use std::env;
// Use platform-appropriate temp directory
let temp_dir = env::temp_dir();
let cache_dir = temp_dir.join("cache");
let bare_path = cache_dir.join("repo.git");
// Clone repository as bare for worktree use
let bare_repo = GitRepo::clone_bare(
"https://github.com/example/repo.git",
&bare_path
).await?;
// Create multiple worktrees for parallel processing
let work1 = temp_dir.join("work1");
let work2 = temp_dir.join("work2");
let work3 = temp_dir.join("work3");
let worktree1 = bare_repo.create_worktree(&work1, Some("v1.0.0")).await?;
let worktree2 = bare_repo.create_worktree(&work2, Some("v2.0.0")).await?;
let worktree3 = bare_repo.create_worktree(&work3, Some("main")).await?;
// Each worktree can be used independently and concurrently
// Process files from worktree1 at v1.0.0
// Process files from worktree2 at v2.0.0
// Process files from worktree3 at latest main
// Clean up when done
bare_repo.remove_worktree(&work1).await?;
bare_repo.remove_worktree(&work2).await?;
bare_repo.remove_worktree(&work3).await?;
§Platform-Specific Considerations
§Windows
- Uses
git.exe
orgit.cmd
detection via PATH - Handles long path names (>260 characters)
- Works with Windows Credential Manager
- Supports both CMD and
PowerShell
environments
§macOS
- Integrates with Xcode Command Line Tools Git
- Supports Keychain authentication
- Handles case-sensitive vs case-insensitive filesystems
§Linux
- Works with package manager installed Git
- Supports various credential helpers
- Handles different filesystem permissions
§Integration with AGPM
This module integrates with other AGPM components:
crate::source
- Repository source managementcrate::manifest
- Manifest-based dependency resolutioncrate::lockfile
- Lockfile generation with commit hashescrate::utils::progress
- User progress feedbackcrate::core::AgpmError
- Centralized error handling
Modules§
- command_
builder - Type-safe Git command builder for consistent command execution
Structs§
- GitRepo
- A Git repository handle providing async operations via CLI commands.
Functions§
- ensure_
git_ available - Ensures Git is available on the system or returns a detailed error.
- ensure_
valid_ git_ repo - Ensures a directory contains a valid Git repository or returns a detailed error.
- is_
git_ installed - Checks if Git is installed and accessible on the system.
- is_
git_ repository - Checks if a path contains a Git repository (regular or bare).
- is_
valid_ git_ repo - Checks if a directory contains a valid Git repository.
- parse_
git_ url - Parses a Git URL into owner and repository name components.
- strip_
auth_ from_ url - Strips authentication information from a Git URL for safe display or logging.