directorytree/git
Lightweight PHP wrapper for running Git commands on a server. Supports pull, fetch, reset (hard/soft), and remote management (get/get all/add/set URL). Requires PHP 7.3+ and a working directory set to your repo via chdir().
Git::pull()).titasgailius/terminal (v1.0), which is stable but not widely adopted. Risk of maintenance gaps if the underlying package deprecates features.getTags()). Could be wrapped in Laravel’s cache layer for performance.terminal package executes raw Git commands. Must validate all inputs (e.g., branch names, commit hashes) to prevent command injection.pull, reset) may fail if PHP’s www-data/apache user lacks repo permissions. Requires explicit chmod/chown or sudo configurations.true/false or empty arrays on failure, which may obscure Git-specific errors (e.g., auth failures, detached HEAD states). Consider wrapping in a custom exception class (e.g., GitOperationFailedException).Terminal::fake(), which may not align with Laravel’s testing tools (Pest/PHPUnit). Could lead to flaky tests if Git state isn’t reset between runs.git cherry-pick or git rebase)?titasgailius/terminal or Git CLI behavior changes (e.g., new flags, deprecations)?league/flysystem-git or php-git (PHP port of Git) offer better abstraction or performance for specific needs?AppServiceProvider:
$this->app->singleton(Git::class, fn() => new Git());
Git facade for cleaner syntax (e.g., Git::pull()) by extending Laravel’s Facade class.php artisan git:pull). Example:
use DirectoryTree\Git\Git;
use Illuminate\Console\Command;
class GitPullCommand extends Command {
protected $git;
public function __construct(Git $git) { $this->git = $git; }
public function handle() { $this->git->pull('main'); }
}
Git into controllers/services where needed. Example:
public function __construct(private Git $git) {}
public function deploy() { $this->git->pull('production'); }
pull, getTags) in a staging environment.Terminal::fake()).Log::debug() for Git commands).getTags()) using Laravel’s cache.class LaravelGitService {
public function __construct(private Git $git) {}
public function safePull(string $branch): bool {
try {
return $this->git->pull($branch);
} catch (\Exception $e) {
Log::error("Git pull failed: {$e->getMessage()}");
return false;
}
}
}
class GitSyncJob implements ShouldQueue {
public function handle() { $git->pull('main'); }
}
PATH configuration.GitPulled) after operations.PATH.open_basedir to allow access to repo directories if using restricted environments.chdir()) before any Git operations.pull --ff-only to avoid merge conflicts).git checkout) if operations modify the repo.directorytree/git and titasgailius/terminal for breaking changes.composer.json to avoid unexpected updates:
"require": {
"directorytree/git": "^1.1",
"titasgailius/terminal": "^1.0"
}
Log::info("Git pull initiated", ['branch' => 'main', 'user' => auth()->id()]);
which git returns a path in PATH.git pull returns 128 for auth failures).Terminal::fake() in tests to simulate failures.git -v pull).git merge --abort").getCommits()) may be slow forHow can I help you explore Laravel packages today?