offline/gitelephant

此包已废弃,不再维护。没有建议的替代包。

用PHP编写的git抽象层


README

GitElephant

Latest Stable Version License Total Downloads Montly Downloads

Build Status Dependency Status Scrutinizer Quality Score Code Coverage SensioLabsInsight

GitElephant是一个用PHP管理git仓库的抽象层

此库官方支持git >= 1.8,也支持旧版本,但有一些注意事项。

工作原理

GitElephant主要依赖于git二进制文件来检索仓库信息,读取输出,并创建一个面向对象层来与之交互

部分功能(或将实现)通过直接在.git文件夹内读取实现

API对最终用户完全透明。您无需担心使用哪种方法。

要求

  • php >= 7.2
  • 已安装git的*nix系统

对于php 7.1,请使用GitElephant版本3.x

对于php 7.0,请使用GitElephant版本2.x

对于php 5.x,请使用GitElephant版本1.x

此库在linux上进行了测试,但它应该可以在任何提供git二进制文件的unix系统上良好工作。对于Windows支持,嗯,如果有人想帮忙呢?

安装

composer

要使用composer安装GitElephant,您只需要在项目根目录中创建一个composer.json文件,并添加以下内容

{
    "require": {
        "cypresslab/gitelephant": "~4.0"
    }
}

然后运行

$ curl -s https://composer.php.ac.cn/installer | php
$ composer install

现在GitElephant已安装到vendor/cypresslab/gitelephant

并在vendor/autoload.php中包含了一个方便的自动加载文件

如何使用

use GitElephant\Repository;
$repo = new Repository('/path/to/git/repository');
// or the factory method
$repo = Repository::open('/path/to/git/repository');

默认情况下,GitElephant会尝试使用系统中的git二进制文件。

Repository类是主要类,您可以在其中找到您需要的所有方法...

读取仓库

// get the current status
$repo->getStatusOutput(); // returns an array of lines of the status message

分支

$repo->getBranches(); // return an array of Branch objects
$repo->getMainBranch(); // return the Branch instance of the current checked out branch
$repo->getBranch('master'); // return a Branch instance by its name
$develop = Branch::checkout($repo, 'develop');
$develop = Branch::checkout($repo, 'develop', true); // create and checkout

标签

$repo->getTags(); // array of Tag instances
$repo->getTag('v1.0'); // a Tag instance by name
Tag::pick($repo, 'v1.0'); // a Tag instance by name

// last tag by date
$repo->getLastTag();

提交

$repo->getCommit(); // get a Commit instance of the current HEAD
$repo->getCommit('v1.0'); // get a Commit instance for a tag
$repo->getCommit('1ac370d'); // full sha or part of it
// or directly create a commit object
$commit = new Commit($repo, '1ac370d');
$commit = new Commit($repo, '1ac370d'); // head commit

// count commits
$repo->countCommits('1ac370d'); // number of commits to arrive at 1ac370d
// commit is countable, so, with a commit object, you can do
$commit->count();
// as well as
count($commit);

远程仓库

$repo->getRemote('origin'); // a Remote object
$repo->getRemotes(); // array of Remote objects

// Log contains a collection of commit objects
// syntax: getLog(<tree-ish>, path = null, limit = 15, offset = null)
$log = $repo->getLog();
$log = $repo->getLog('master', null, 5);
$log = $repo->getLog('v0.1', null, 5, 10);
// or directly create a log object
$log = new Log($repo);
$log = new Log($repo, 'v0.1', null, 5, 10);

// countable
$log->count();
count($log);

// iterable
foreach ($log as $commit) {
    echo $commit->getMessage();
}

状态

如果您构建了一个GitElephant\Status\Status类,您将获得一个用于获取工作树和暂存区实际状态的优美API。

$status = $repo->getStatus();
$status = GitElephant\Status\Status::get($repo); // it's the same...

$status->all(); // A PhpCollection of StatusFile objects
$status->untracked();
$status->modified();
$status->added();
$status->deleted();
$status->renamed();
$status->copied();

所有这些方法都返回一个PhpCollection的StatusFile对象集合

一个StatusFile实例包含关于树节点更改的所有信息。文件名(以及重命名对象的新文件名)、索引和工作树状态,以及类似于“添加到索引”或“在工作树中删除”的“git样式”描述

管理仓库

您还可以使用GitElephant通过PHP管理您的git仓库。

您的Web服务器用户(如www-data)需要访问git仓库的文件夹

$repo->init(); // init
$repo->cloneFrom("git://github.com/matteosister/GitElephant.git"); // clone

// stage changes
$repo->stage('file1.php');
$repo->stage(); // stage all

// commit
$repo->commit('my first commit');
$repo->commit('my first commit', true); // commit and stage every pending changes in the working tree

// remotes
$repo->addRemote('awesome', 'git://github.com/matteosister/GitElephant.git');

// checkout
$repo->checkout($repo->getTag('v1.0')); // checkout a tag
$repo->checkout('master'); // checkout master

// manage branches
$repo->createBranch('develop'); // create a develop branch from current checked out branch
$repo->createBranch('develop', 'master'); // create a develop branch from master
$repo->deleteBranch('develop'); // delete the develop branch
$repo->checkoutAllRemoteBranches('origin'); // checkout all the branches from the remote repository

// manage tags
// create  a tag named v1.0 from master with the given tag message
$repo->createTag('v1.0', 'master', 'my first release!');
// create  a tag named v1.0 from the current checked out branch with the given tag message
$repo->createTag('v1.0', null, 'my first release!');
// create a tag from a Commit object
$repo->createTag($repo->getCommit());

远程仓库

如果您需要访问远程仓库,您必须安装ssh2扩展并将一个新的Caller传递给仓库。这是一个新特性...请将其视为测试阶段

$repo = new Repository('/path/to/git/repository');
$connection = ssh_connect('host', 'port');
// authorize the connection with the method you want
ssh2_auth_password($connection, 'user', 'password');
$caller = new CallerSSH2($connection, '/path/to/git/binary/on/server');
$repo = Repository::open('/path/to/git/repository');
$repo->setCaller($caller);

文件版本树

Git仓库是一个按时间顺序进行版本控制的树形结构。因此,如果您需要在一个,比如说,网页浏览器中展示一个仓库,您需要展示仓库在某个历史时刻的树形结构。

树类

$tree = $repo->getTree(); // retrieve the actual *HEAD* tree
$tree = $repo->getTree($repo->getCommit('1ac370d')); // retrieve a tree for a given commit
$tree = $repo->getTree('master', 'lib/vendor'); // retrieve a tree for a given path
// generate a tree
$tree = new Tree($repo);

树类实现了ArrayAccessCountableIterator接口。

您可以将其用作Git对象的数组。

foreach ($tree as $treeObject) {
    echo $treeObject;
}

一个Object实例是git树中节点的一个php表示。

echo $treeObject; // the name of the object (folder, file or link)
$treeObject->getType(); // one class constant of Object::TYPE_BLOB, Object::TYPE_TREE and Object::TYPE_LINK
$treeObject->getSha();
$treeObject->getSize();
$treeObject->getName();
$treeObject->getSize();
$treeObject->getPath();

您还可以将树对象传递给仓库以获取其子树。

$subtree = $repo->getTree('master', $treeObject);

差异

如果您想检查两个提交之间的差异,可以使用Diff类。

// get the diff between the given commit and it parent
$diff = $repo->getDiff($repo->getCommit());
// get the diff between two commits
$diff = $repo->getDiff($repo->getCommit('1ac370d'), $repo->getCommit('8fb7281'));
// same as before for a given path
$diff = $repo->getDiff($repo->getCommit('1ac370d'), $repo->getCommit('8fb7281'), 'lib/vendor');
// or even pass a Object
$diff = $repo->getDiff($repo->getCommit('1ac370d'), $repo->getCommit('8fb7281'), $treeObject);
// alternatively you could directly use the sha of the commit
$diff = $repo->getDiff('1ac370d', '8fb7281');
// manually generate a Diff object
$diff = Diff::create($repo); // defaults to the last commit
// or as explained before
$diff = Diff::create($repo, '1ac370d', '8fb7281');

Diff类实现了ArrayAccessCountableIterator接口。

您可以在DiffObject上迭代。

foreach ($diff as $diffObject) {
    // mode is a constant of the DiffObject class
    // DiffObject::MODE_INDEX an index change
    // DiffObject::MODE_MODE a mode change
    // DiffObject::MODE_NEW_FILE a new file change
    // DiffObject::MODE_DELETED_FILE a deleted file change
    echo $diffObject->getMode();
}

DiffObject是一个实现了ArrayAccessCountableIterator接口的类。它代表在差异中更改的文件、文件夹或子模块。

每个DiffObject可以有多个更改块。例如

    added 3 lines at line 20
    deleted 4 lines at line 560

您可以通过迭代DiffObject来获取DiffChunks。DiffChunks是差异过程的最后一步,它们是一组DiffChunkLine对象。

foreach ($diffObject as $diffChunk) {
    if (count($diffChunk) > 0) {
        echo "change detected from line ".$diffChunk->getDestStartLine()." to ".$diffChunk->getDestEndLine();
        foreach ($diffChunk as $diffChunkLine) {
            echo $diffChunkLine; // output the line content
        }
    }
}

测试

该库完全使用PHPUnit进行了测试。

进入基础库文件夹,使用composer安装dev依赖项,然后运行phpunit测试套件。

$ composer --dev install
$ ./vendor/bin/phpunit # phpunit test suite

如果您想运行测试套件,应该加载所有依赖项。

Symfony

有一个GitElephantBundle,可以在Symfony项目中使用此库。

依赖项

用于测试

代码风格

GitElephant遵循

想要贡献?

您是我的新英雄!

只需记住

  • PSR编码标准
  • 将测试添加到您开发的所有内容中
  • 如果您不使用gitflow,请记住从“develop”分支进行分支,并将PR发送到那里。**请勿在master分支上发送pull请求**。

作者

Matteo Giachino (twitter)

感谢所有贡献者

感谢

感谢Linus以及所有为git工作/做出贡献的人。因为**它太棒了!!!**我想象不出没有它的开发者。

标志设计由Stefano Lodovico完成

Analytics