NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Git for Laravel

Pull requests, issues & files

Every other read follows the same pattern — lists return a Page, single resources return a typed object:

$repo = Git::github()->repo('acme/api');

$repo->pullRequests();                         // Page<PullRequest>, open by default
$repo->pullRequests('closed', perPage: 50);
$repo->pullRequest(7)->get();                  // GitLab MRs, Bitbucket PRs
$repo->issues();                               // Page<Issue>
$repo->issue(12);
$repo->tags();                                 // Page<Tag>
$repo->releases();                             // Page<Release>
$repo->release('v1.0');                        // by tag or id
$repo->contents('README.md', ref: 'main');     // FileContent (decoded); no ref = the default branch
$repo->compare('main', 'feature');             // Comparison
$repo->contributors();                         // Page<Contributor>
$repo->languages();                            // ['PHP' => 12345, ...]

pullRequests() and issues() take a state (open by default); the package translates it into each forge’s own spelling, so open means opened on GitLab and OPEN on Bitbucket. GitLab merge requests and Bitbucket pull requests come back as the same PullRequest object. contents() without a ref reads the default branch on every forge.

Files and diffs

$repo = Git::github()->repo('acme/api');

$file = $repo->contents('composer.json', ref: 'main');
$file->path;      // "composer.json"
$file->content;   // the decoded file body
$file->sha;       // blob sha — what updateFile() needs
$file->size;      // bytes

$diff = $repo->compare('main', 'feature/ci');
$diff->aheadBy;
$diff->behindBy;

foreach ($diff->files as $changed) {    // list<ComparisonFile>
    $changed->filename;
    $changed->status;                   // e.g. "modified"
    $changed->additions;
    $changed->deletions;
}

Result objects

ObjectFields
PullRequestprovider, id, number, title, body, state, sourceBranch, targetBranch, author, url, createdAt, draft
Issueprovider, id, number, title, body, state, author, url, createdAt
Tagprovider, name, sha, url
Releaseprovider, id, tagName, name, body, draft, prerelease, url, createdAt
FileContentpath, content (decoded), sha, size, url
Comparisonbase, head, aheadBy, behindBy, files (list of ComparisonFile: filename, status, additions, deletions)
Contributorid, name, avatar, contributions
Commentid, body, author, url, createdAt
Author / Ownername, email, avatar / id, name, avatar

Capabilities differ per provider — Bitbucket has no issues, tags or releases here, for instance. Calling one a provider doesn’t support throws FeatureNotSupportedException; see Feature detection to branch on support instead.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.