PHPackages                             vanilla/garden-git - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. vanilla/garden-git

ActiveProject

vanilla/garden-git
==================

A PHP library for working with git and github.

v3.3(2mo ago)16.0k↓74.3%MITPHPPHP &gt;=8.0CI passing

Since Jan 28Pushed 2mo ago5 watchersCompare

[ Source](https://github.com/vanilla/garden-git)[ Packagist](https://packagist.org/packages/vanilla/garden-git)[ RSS](/packages/vanilla-garden-git/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (5)Versions (26)Used By (0)

vanilla/garden-git
==================

[](#vanillagarden-git)

An object-oriented PHP library for working Git.

[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](https://opensource.org/licenses/MIT)[![GitHub release (latest SemVer)](https://camo.githubusercontent.com/20c1158fcca399b5cb9ecd44ad57c27f2e0c808aac1d3e0a96d0c62590b1fb3e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f76616e696c6c612f67617264656e2d6769743f6c6162656c3d72656c65617365)](https://camo.githubusercontent.com/20c1158fcca399b5cb9ecd44ad57c27f2e0c808aac1d3e0a96d0c62590b1fb3e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f76616e696c6c612f67617264656e2d6769743f6c6162656c3d72656c65617365)[![CircleCI](https://camo.githubusercontent.com/efc34ec4b035d91d4c4c9838c42aa1d594670791a231ec5c549f20cf5757b979/68747470733a2f2f636972636c6563692e636f6d2f67682f76616e696c6c612f67617264656e2d6769742f747265652f6d61737465722e7376673f7374796c653d737667)](https://circleci.com/gh/vanilla/garden-git/tree/master)[![codecov](https://camo.githubusercontent.com/4f7bef9a1301a83bb174a0b14b9b6b1dbc14e97cf650d421bbf683bad5962973/68747470733a2f2f636f6465636f762e696f2f67682f76616e696c6c612f67617264656e2d6769742f6272616e63682f6d61737465722f67726170682f62616467652e7376673f746f6b656e3d7a314147757135483777)](https://codecov.io/gh/vanilla/garden-git)

Installation
------------

[](#installation)

```
composer require vanilla/garden-git
```

Features
--------

[](#features)

- Ability to call arbitrary git commands with nicely wrapped process output.
- Object-oriented wrappers around common git operations.
    - Branches
    - Commits
    - Remotes
    - Tags
    - Authors
    - File staging and restoration.
- PHPUnit test harness w/ 100% test coverage.

Usage
-----

[](#usage)

**Common Patterns**

- All methods may throw a `Garden\Git\Exception\GitException` if there is a problem.
- `find` methods return null if an item is not found.
- `get` methods throw if a `Garden\Git\Exception\NotFoundException` item is not found.

```
use Garden\Git;

// Will throw if path isn't the root of a git repo.
$repo = new Git\Repository('/path/to/repo');

// Run any git command.
// Will throw a `GitException` with the failed process output
// if git returns a non-0 exit code.
// Otherwise returns the string output from git.
$repo->git(['rebase', 'master'])

// Commits
$newCommit = $repo->commit("Commit")
$existingCommit = $repo->getCommit("asdf4asd31kl3jkll41");

// Working with a commit.
$newCommit->getAuthor();
$newCommit->getCommitHash();
$newCommit->getDate();
$newCommit->getMessage();

// Get commit author
$author = $existingCommit->getAuthor();
$author->getEmail();
$author->getName();

// List Branches
$branches = $repo->getBranches();

// A string, Git\Branch or Git\PartialBranch can be used here.
$existingBranch = $repo->findBranch('branch/name');
$existingBranch = $repo->getBranch(new Git\PartialBranch('branch/name'));

// Working with branches
$existingBranch->getName();
$existingBranch->getCommitHash();
$existingBranch->getRemoteBranchName();
$existingBranch->getRemoteName();

// Create a branch
$newBranch = $repo->createBranch("new/branch-name", new Git\Head());
$newBranch = $repo->createBranch("new/branch-name", $existingBranch);
$newBranch = $repo->createBranch("new/branch-name", new Git\PartialBranch("old/branch-name"));
$newBranch = $repo->createBranch("new/branch-name", $existingCommit);

// Delete branch
$repo->deleteBranch($newBranch);

// List Tags
$tags = $repo->getTags();
$tags = $repo->getTags($existingCommit); // Get only tags reachable on this commit.
$tags = $repo->getTags($existingBranch); // Get only tags reachable on a branch.

// Sorting
$tags = $repo->getTags(new Git\Head(), Git\Tag::SORT_NEWEST_COMMIT);
$tags = $repo->getTags(new Git\Head(), Git\Tag::SORT_NEWEST_VERSION);

// Lookup a tag
$existingTag = $repo->findTag("v1.2.0");
$existingTag = $repo->getTag("v1.2.0");

// Working with tags
$existingTag->getName();
$existingTag->getMessage();
$existingTag->getDate();
$existingTag->getAuthor();
$existingTag->getCommit();

// Create a tag
$newTag = $repo->tagCommit($existingCommit, "v1.3.0", "Tag description");
$newTag = $repo->tagCommit($existingBranch, "v1.3.0", "Tag description");
$newTag = $repo->tagCommit(new Git\Head(), "v1.3.0", "Tag description");

// Get the info from a tag.
$commit = $newTag->getCommit();
$commitAuthor = $newTag->getCommit()->getAuthor();
$tagAuthor = $newTag->getAuthor();

// Delete a tag
$repo->deleteTag($newTag);

// Get remotes
$remotes = $repo->getRemotes();
$existingRemote = $repo->findRemote("origin");
$existingRemote = $repo->getRemote("origin");

// Working with  remote.
$existingRemote->getName();
$existingRemote->getUri();
$existingRemote->canFetch();
$existingRemote->canPush();

// Create remote
$newRemote = $repo->addRemote(new Git\Remote(
    "alt-origin",
    "git@github.com:vanilla/vanilla-cloud.git"
))

// Fetch data from the remote.
// You'll likely want to run this after creating a remote.
$repo->fetchFromRemote($newRemote);
foreach ($repo->fetchFromRemoteIterator($remote) as $gitOutputLine) {
    // Allows you to render some progress during the fetch.
}

// Remote a remote
$repo->removeRemote($newRemote);

// Pull a branch from a remote.
// Git itself often uses the remote branch name as your local name automatically.
// This method makes you explicitly declare that.
$branch = $repo->createBranchFromRemote(
    new Git\PartialBranch("local-branch-name"),
    $existingRemote,
    "remote-branch-name",
);

// Push to a remote.
$repo->pushBranch($branch, $existingRemote);

// Delete branch locally and on remote.
$repo->deleteBranch($branch, true);

// Statuses
$status = $repo->getStatus();
$files = $status->getFiles();
$files = $status->getAdded();
$files = $status->getDeleted();
$files = $status->getModified();
$files = $status->getIgnored();
$files = $status->getStagedFiles();
$files = $status->getUnstagedFiles();
$files = $status->hasChanges();
$files = $status->hasUnstagedChanges();
$renamedfiles = $status->getRenamed();

// Working with files;
$files[0]->getPath();
$files[0]->hasStaged();
$files[0]->hasUnstaged();
$renamedFiles[0]->getOldPath();

// Manipulating staging area.
$status = $repo->stageFiles(["/dir1", "/dir2", "file1"]);
$status = $repo->unstageFiles(["/dir1", "/dir2", "file1"]);

// Copy files from another branch.
$status = $repo->restoreFiles(["/dir1", "/dir2", "file1"], $branch);

// Clear out all uncommitted file changes.
$status =$repo->resetFiles();
```

Contributing
------------

[](#contributing)

Think there's a key feature missing? Pull requests will be accepted if they pass CI and they have full code coverage.

**Setting up the Repo**

```
composer install
```

**Running Tests**

```
composer tests

# Run and generate code coverage
composer tests:coverage
```

- They pass the CI tests.
- They come with full test coverage.

###  Health Score

50

—

FairBetter than 96% of packages

Maintenance86

Actively maintained with recent releases

Popularity25

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 79.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~90 days

Recently: every ~105 days

Total

17

Last Release

66d ago

Major Versions

v0.1.0 → v1.0.02022-01-30

v1.1.1 → v2.0.12022-07-08

v1.2.0 → v2.0.02022-07-08

v1.2.2 → v3.02024-11-21

v1.3 → v3.12025-03-14

PHP version history (3 changes)v0.1.0PHP &gt;=7.2

v2.0.2PHP &gt;=7.4

v3.0PHP &gt;=8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/da29e060f227028e8ee38bb5873ba2188fb5236b20b3dffec766c768019d8bd8?d=identicon)[tburry](/maintainers/tburry)

![](https://www.gravatar.com/avatar/ea17fedfd653c4692cf93a4faada50927cef9537dafed0dd4b1517e54fd71728?d=identicon)[charrondev](/maintainers/charrondev)

---

Top Contributors

[![charrondev](https://avatars.githubusercontent.com/u/1770056?v=4)](https://github.com/charrondev "charrondev (23 commits)")[![acharron-hl](https://avatars.githubusercontent.com/u/146114816?v=4)](https://github.com/acharron-hl "acharron-hl (4 commits)")[![OlivierLamyCanuel](https://avatars.githubusercontent.com/u/39598345?v=4)](https://github.com/OlivierLamyCanuel "OlivierLamyCanuel (1 commits)")[![vanilla-dbarbier](https://avatars.githubusercontent.com/u/61435952?v=4)](https://github.com/vanilla-dbarbier "vanilla-dbarbier (1 commits)")

---

Tags

production

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/vanilla-garden-git/health.svg)

```
[![Health](https://phpackages.com/badges/vanilla-garden-git/health.svg)](https://phpackages.com/packages/vanilla-garden-git)
```

###  Alternatives

[temporal/sdk

Temporal SDK

3971.9M14](/packages/temporal-sdk)[twigstan/twigstan

TwigStan is a static analyzer for Twig templates powered by PHPStan

27311.4k](/packages/twigstan-twigstan)[sensiolabs/minify-bundle

Assets Minifier (CSS, JS) for Symfony &amp; Minify integration in Asset Mapper

5678.5k1](/packages/sensiolabs-minify-bundle)[asgardcms/asgardcms-installer

AsgardCms application installer.

2842.6k](/packages/asgardcms-asgardcms-installer)[drevops/git-artifact

Package artifact from your codebase in CI and push it to a separate git repo.

2132.4k](/packages/drevops-git-artifact)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
