Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Git State Laravel Package

sebastian/git-state

sebastian/git-state is a small PHP library that inspects a Git checkout and reports its state: origin URL, current branch, commit hash, and whether the working directory is clean (or the current git status). Useful for build/test tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps for Laravel Developers

  1. Installation: Add to composer.json (or run):

    composer require sebastian/git-state
    

    For dev-only (e.g., testing):

    composer require --dev sebastian/git-state
    
  2. First Usage: Inject the Builder into a Service Provider, Artisan Command, or Controller:

    use SebastianBergmann\GitState\Builder;
    
    public function checkGitState()
    {
        $builder = new Builder();
        $state = $builder->build();
    
        if (!$state) {
            return response()->json(['error' => 'Not a Git repo or missing origin'], 400);
        }
    
        return [
            'branch' => $state->branch(),
            'commit' => $state->commit(),
            'is_clean' => $state->isClean(),
        ];
    }
    
  3. Quick Win: Use in a CI/CD pipeline to block dirty deploys:

    // In a GitHub Actions step or Laravel command
    $state = (new Builder())->build();
    if (!$state || !$state->isClean()) {
        throw new \RuntimeException('Deployment aborted: Uncommitted changes detected.');
    }
    
  4. Where to Look First:

    • Builder class: Core entry point for creating state snapshots.
    • State object methods:
      • originUrl(): Remote repository URL.
      • branch(): Current branch name.
      • commit(): Latest commit hash.
      • isClean(): Boolean for working directory status.
      • status(): Raw git status output (if dirty).
    • Error Handling: build() returns false for non-Git repos or missing origins.

Implementation Patterns

Core Workflows

1. Git State Validation in Middleware

Enforce clean working directories for API requests:

namespace App\Http\Middleware;

use Closure;
use SebastianBergmann\GitState\Builder;

class GitStateMiddleware
{
    public function handle($request, Closure $next)
    {
        $state = (new Builder())->build();
        if (!$state || !$state->isClean()) {
            return response()->json(['error' => 'Git validation failed'], 403);
        }
        return $next($request);
    }
}

Register in app/Http/Kernel.php:

protected $middleware = [
    \App\Http\Middleware\GitStateMiddleware::class,
];

2. Artisan Commands for CLI Tools

Create a command to inspect Git state:

php artisan make:command GitStatus
// app/Console/Commands/GitStatus.php
protected function handle()
{
    $state = (new Builder())->build();
    if (!$state) {
        $this->error('Not a Git repository or missing origin.');
        return;
    }

    $this->info("Branch: {$state->branch()}");
    $this->info("Commit: {$state->commit()}");
    $this->info("Origin: {$state->originUrl()}");
    if (!$state->isClean()) {
        $this->error("Dirty working directory:\n" . $state->status());
    }
}

3. Service Layer for Reusability

Encapsulate logic in a service for dependency injection:

namespace App\Services;

use SebastianBergmann\GitState\Builder;

class GitService
{
    public function getState()
    {
        $builder = new Builder();
        $state = $builder->build();
        return $state ? [
            'branch' => $state->branch(),
            'commit' => $state->commit(),
            'is_clean' => $state->isClean(),
        ] : null;
    }
}

Use in controllers:

public function showGitInfo(GitService $gitService)
{
    return response()->json($gitService->getState());
}

4. CI/CD Pipeline Integration

Add a Git state check to Laravel’s app/Console/Kernel.php for pre-deployment:

protected function schedule(Schedule $schedule)
{
    $schedule->command('git:validate')->before('deploy');
}

Create the command:

// app/Console/Commands/GitValidate.php
protected function handle()
{
    $state = (new Builder())->build();
    if (!$state || !$state->isClean()) {
        $this->error('Git validation failed. Aborting deployment.');
        exit(1);
    }
    $this->info('Git state validated successfully.');
}

5. Dynamic Feature Flags

Use commit hashes or branches to toggle features:

public function featureEnabled(Request $request)
{
    $state = (new Builder())->build();
    $commit = $state?->commit();
    return $commit === 'abc123' ? true : false;
}

Integration Tips

  • Laravel Facades: Create a facade for cleaner syntax:

    // app/Providers/AppServiceProvider.php
    public function boot()
    {
        $this->app->bind('git', function () {
            return new Builder();
        });
    }
    

    Usage:

    $state = app('git')->build();
    
  • Caching Git State: Cache results in Redis for performance (e.g., in microservices):

    use Illuminate\Support\Facades\Cache;
    
    public function getCachedState()
    {
        return Cache::remember('git.state', now()->addMinutes(5), function () {
            return (new Builder())->build();
        });
    }
    
  • Error Handling: Wrap build() in a try-catch for robustness:

    try {
        $state = (new Builder())->build();
    } catch (\Exception $e) {
        Log::error("Git state check failed: " . $e->getMessage());
        return false;
    }
    
  • Testing: Mock the Builder in PHPUnit:

    $mockBuilder = Mockery::mock(Builder::class);
    $mockBuilder->shouldReceive('build')->andReturn($mockState);
    $this->app->instance(Builder::class, $mockBuilder);
    

Gotchas and Tips

Pitfalls

  1. Non-Git Directories:

    • build() returns false if not in a Git repo. Always check:
      $state = (new Builder())->build();
      if (!$state) { /* Handle error */ }
      
  2. Missing Origin Remote:

    • originUrl() may return null if no remote is configured. Validate:
      if (!$state->originUrl()) {
          throw new \RuntimeException('No Git origin configured.');
      }
      
  3. Git Command Failures:

    • Underlying git commands may fail silently. Use Laravel’s Process facade for better error handling:
      use Illuminate\Support\Facades\Process;
      
      $output = Process::run('git status');
      if ($output->failed()) {
          Log::error("Git command failed: " . $output->errorOutput());
      }
      
  4. Permissions Issues:

    • If .git directory is inaccessible (e.g., Docker permissions), build() will fail. Ensure:
      • Correct file permissions in containers (e.g., chmod -R 755 .git).
      • Git is installed in the container’s PATH.
  5. Dirty Working Directory:

    • isClean() returns false for staged/unstaged changes. Use status() to debug:
      if (!$state->isClean()) {
          Log::warning("Dirty status:\n" . $state->status());
      }
      
  6. Git Version Compatibility:

    • Older Git versions may return unexpected output. Test with:
      git --version
      
    • Document minimum Git version requirements (e.g., "Git 2.10+").
  7. Network Dependencies:

    • originUrl() requires network access. In air-gapped environments, it may fail. Cache or mock:
      $origin = Cache::remember('git.origin', now()->addHours(1), function () {
          return (new Builder())->build()?->originUrl();
      });
      

Debugging Tips

  • Log Raw Output: Log the raw git status for debugging:

    Log::debug("Git status: " . $state->status());
    
  • Check Git Environment: Verify Git is available in your environment:

    which git
    git --version
    
  • Mock for Testing: Use Mockery to simulate Git states in tests:

    $mockState = Mockery::mock(\SebastianBergmann\GitState\State::class);
    $mockState->shouldReceive('branch')->andReturn('main');
    $mockState
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
boundwize/jsonrecast
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata