mirror of
https://github.com/klaussilveira/gitlist.git
synced 2025-11-18 03:30:55 +01:00
Initial commit
This commit is contained in:
122
lib/Git/Client.php
Normal file
122
lib/Git/Client.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Git;
|
||||
|
||||
class Client
|
||||
{
|
||||
protected $path;
|
||||
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->setPath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new repository on the specified path
|
||||
*
|
||||
* @param string $path Path where the new repository will be created
|
||||
* @return Repository Instance of Repository
|
||||
*/
|
||||
public function createRepository($path)
|
||||
{
|
||||
if (file_exists($path . '/.git/HEAD') && !file_exists($path . '/HEAD')) {
|
||||
throw new \RuntimeException('A GIT repository already exists at ' . $path);
|
||||
}
|
||||
|
||||
$repository = new Repository($path, $this);
|
||||
return $repository->create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a repository at the specified path
|
||||
*
|
||||
* @param string $path Path where the repository is located
|
||||
* @return Repository Instance of Repository
|
||||
*/
|
||||
public function getRepository($path)
|
||||
{
|
||||
if (!file_exists($path) || !file_exists($path . '/.git/HEAD') && !file_exists($path . '/HEAD')) {
|
||||
throw new \RuntimeException('There is no GIT repository at ' . $path);
|
||||
}
|
||||
|
||||
return new Repository($path, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for valid repositories on the specified path
|
||||
*
|
||||
* @param string $path Path where repositories will be searched
|
||||
* @return array Found repositories, containing their name, path and description
|
||||
*/
|
||||
public function getRepositories($path)
|
||||
{
|
||||
$dir = new \DirectoryIterator($path);
|
||||
|
||||
foreach ($dir as $file) {
|
||||
$isBare = file_exists($file->getPathname() . '/HEAD');
|
||||
$isRepository = file_exists($file->getPathname() . '/.git/HEAD');
|
||||
|
||||
if ($file->isDir() && !$file->isDot() && $isRepository || $isBare) {
|
||||
if ($isBare) {
|
||||
$description = file_get_contents($file->getPathname() . '/description');
|
||||
} else {
|
||||
$description = file_get_contents($file->getPathname() . '/.git/description');
|
||||
}
|
||||
|
||||
$repositories[] = array('name' => $file->getFilename(), 'path' => $file->getPathname(), 'description' => $description);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($repositories)) {
|
||||
throw new \RuntimeException('There are no GIT repositories in ' . $path);
|
||||
}
|
||||
|
||||
sort($repositories);
|
||||
|
||||
return $repositories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a git command on the repository being manipulated
|
||||
*
|
||||
* This method will start a new process on the current machine and
|
||||
* run git commands. Once the command has been run, the method will
|
||||
* return the command line output.
|
||||
*
|
||||
* @param Repository $repository Repository where the command will be run
|
||||
* @param string $command Git command to be run
|
||||
* @return string Returns the command output
|
||||
*/
|
||||
public function run(Repository $repository, $command)
|
||||
{
|
||||
$descriptors = array(0 => array("pipe", "r"), 1 => array("pipe", "w"));
|
||||
$process = proc_open($this->getPath() . ' ' . $command, $descriptors, $pipes, $repository->getPath());
|
||||
|
||||
if (is_resource($process)) {
|
||||
$stdout = stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
proc_close($process);
|
||||
return $stdout;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Git binary path
|
||||
*
|
||||
* @return string Path where the Git binary is located
|
||||
*/
|
||||
protected function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current Git binary path
|
||||
*
|
||||
* @param string $path Path where the Git binary is located
|
||||
*/
|
||||
protected function setPath($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
}
|
||||
35
lib/Git/Commit/Author.php
Normal file
35
lib/Git/Commit/Author.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Git\Commit;
|
||||
|
||||
class Author
|
||||
{
|
||||
protected $name;
|
||||
protected $email;
|
||||
|
||||
public function __construct($name, $email)
|
||||
{
|
||||
$this->setName($name);
|
||||
$this->setEmail($email);
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function setEmail($email)
|
||||
{
|
||||
$this->email = $email;
|
||||
}
|
||||
}
|
||||
148
lib/Git/Commit/Commit.php
Normal file
148
lib/Git/Commit/Commit.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace Git\Commit;
|
||||
|
||||
class Commit
|
||||
{
|
||||
protected $hash;
|
||||
protected $shortHash;
|
||||
protected $treeHash;
|
||||
protected $parentHash;
|
||||
protected $author;
|
||||
protected $date;
|
||||
protected $commiter;
|
||||
protected $commiterDate;
|
||||
protected $message;
|
||||
protected $diffs;
|
||||
|
||||
public function importData(array $data)
|
||||
{
|
||||
$this->setHash($data['hash']);
|
||||
$this->setShortHash($data['short_hash']);
|
||||
$this->setTreeHash($data['tree']);
|
||||
$this->setParentHash($data['parent']);
|
||||
|
||||
$this->setAuthor(
|
||||
new Author($data['author'], $data['author_email'])
|
||||
);
|
||||
|
||||
$this->setDate(
|
||||
new \DateTime('@' . $data['date'])
|
||||
);
|
||||
|
||||
$this->setCommiter(
|
||||
new Author($data['commiter'], $data['commiter_email'])
|
||||
);
|
||||
|
||||
$this->setCommiterDate(
|
||||
new \DateTime('@' . $data['commiter_date'])
|
||||
);
|
||||
|
||||
$this->setMessage($data['message']);
|
||||
}
|
||||
|
||||
public function getHash()
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
public function setHash($hash)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
public function getShortHash()
|
||||
{
|
||||
return $this->shortHash;
|
||||
}
|
||||
|
||||
public function setShortHash($shortHash)
|
||||
{
|
||||
$this->shortHash = $shortHash;
|
||||
}
|
||||
|
||||
public function getTreeHash()
|
||||
{
|
||||
return $this->treeHash;
|
||||
}
|
||||
|
||||
public function setTreeHash($treeHash)
|
||||
{
|
||||
$this->treeHash = $treeHash;
|
||||
}
|
||||
|
||||
public function getParentHash()
|
||||
{
|
||||
return $this->parentHash;
|
||||
}
|
||||
|
||||
public function setParentHash($parentHash)
|
||||
{
|
||||
$this->parentHash = $parentHash;
|
||||
}
|
||||
|
||||
public function getAuthor()
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
public function setAuthor($author)
|
||||
{
|
||||
$this->author = $author;
|
||||
}
|
||||
|
||||
public function getDate()
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function setDate($date)
|
||||
{
|
||||
$this->date = $date;
|
||||
}
|
||||
|
||||
public function getCommiter()
|
||||
{
|
||||
return $this->commiter;
|
||||
}
|
||||
|
||||
public function setCommiter($commiter)
|
||||
{
|
||||
$this->commiter = $commiter;
|
||||
}
|
||||
|
||||
public function getCommiterDate()
|
||||
{
|
||||
return $this->commiterDate;
|
||||
}
|
||||
|
||||
public function setCommiterDate($commiterDate)
|
||||
{
|
||||
$this->commiterDate = $commiterDate;
|
||||
}
|
||||
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
public function setMessage($message)
|
||||
{
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public function getDiffs()
|
||||
{
|
||||
return $this->diffs;
|
||||
}
|
||||
|
||||
public function setDiffs($diffs)
|
||||
{
|
||||
$this->diffs = $diffs;
|
||||
}
|
||||
|
||||
public function getChangedFiles()
|
||||
{
|
||||
return sizeof($this->diffs);
|
||||
}
|
||||
}
|
||||
23
lib/Git/GitServiceProvider.php
Normal file
23
lib/Git/GitServiceProvider.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Git;
|
||||
|
||||
use Silex\Application;
|
||||
use Silex\ServiceProviderInterface;
|
||||
|
||||
class GitServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Register the Git\Client on the Application ServiceProvider
|
||||
*
|
||||
* @param Application $app Silex Application
|
||||
* @return Git\Client Instance of the Git\Client
|
||||
*/
|
||||
public function register(Application $app)
|
||||
{
|
||||
$app['git'] = function () use ($app) {
|
||||
$default = $app['git.client'] ? $app['git.client'] : '/usr/bin/git';
|
||||
return new Client($app['git.client']);
|
||||
};
|
||||
}
|
||||
}
|
||||
67
lib/Git/Model/Blob.php
Normal file
67
lib/Git/Model/Blob.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Git\Model;
|
||||
|
||||
use Git\Client;
|
||||
use Git\Repository;
|
||||
use Git\ScopeAware;
|
||||
|
||||
class Blob extends ScopeAware
|
||||
{
|
||||
protected $mode;
|
||||
protected $hash;
|
||||
protected $name;
|
||||
protected $size;
|
||||
|
||||
public function __construct($hash, Client $client, Repository $repository) {
|
||||
$this->setClient($client);
|
||||
$this->setRepository($repository);
|
||||
$this->setHash($hash);
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
$data = $this->getClient()->run($this->getRepository(), 'show ' . $this->getHash());
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getMode()
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
public function setMode($mode)
|
||||
{
|
||||
$this->mode = $mode;
|
||||
}
|
||||
|
||||
public function getHash()
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
public function setHash($hash)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function setSize($size)
|
||||
{
|
||||
$this->size = $size;
|
||||
}
|
||||
}
|
||||
60
lib/Git/Model/Diff.php
Normal file
60
lib/Git/Model/Diff.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Git\Model;
|
||||
|
||||
use Git\Model\Line;
|
||||
|
||||
class Diff
|
||||
{
|
||||
protected $lines;
|
||||
protected $index;
|
||||
protected $old;
|
||||
protected $new;
|
||||
protected $file;
|
||||
|
||||
public function addLine($line)
|
||||
{
|
||||
$this->lines[] = new Line($line);
|
||||
}
|
||||
|
||||
public function getLines()
|
||||
{
|
||||
return $this->lines;
|
||||
}
|
||||
|
||||
public function setIndex($index)
|
||||
{
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
public function getIndex()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
public function setOld($old)
|
||||
{
|
||||
$this->old = $old;
|
||||
}
|
||||
|
||||
public function getOld()
|
||||
{
|
||||
return $this->old;
|
||||
}
|
||||
|
||||
public function setNew($new)
|
||||
{
|
||||
$this->new = $new;
|
||||
$this->file = substr($new, 6);
|
||||
}
|
||||
|
||||
public function getNew()
|
||||
{
|
||||
return $this->new;
|
||||
}
|
||||
|
||||
public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
}
|
||||
48
lib/Git/Model/Line.php
Normal file
48
lib/Git/Model/Line.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Git\Model;
|
||||
|
||||
class Line
|
||||
{
|
||||
protected $line;
|
||||
protected $type;
|
||||
|
||||
public function __construct($data)
|
||||
{
|
||||
if (!empty($data)) {
|
||||
if ($data[0] == '@') {
|
||||
$this->setType('chunk');
|
||||
}
|
||||
|
||||
if ($data[0] == '-') {
|
||||
$this->setType('old');
|
||||
}
|
||||
|
||||
if ($data[0] == '+') {
|
||||
$this->setType('new');
|
||||
}
|
||||
}
|
||||
|
||||
$this->setLine($data);
|
||||
}
|
||||
|
||||
public function getLine()
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
public function setLine($line)
|
||||
{
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
44
lib/Git/Model/Symlink.php
Normal file
44
lib/Git/Model/Symlink.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Git\Model;
|
||||
|
||||
use Git\Client;
|
||||
use Git\Repository;
|
||||
use Git\ScopeAware;
|
||||
|
||||
class Symlink
|
||||
{
|
||||
protected $mode;
|
||||
protected $name;
|
||||
protected $path;
|
||||
|
||||
public function getMode()
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
public function setMode($mode)
|
||||
{
|
||||
$this->mode = $mode;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
}
|
||||
172
lib/Git/Model/Tree.php
Normal file
172
lib/Git/Model/Tree.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace Git\Model;
|
||||
|
||||
use Git\Client;
|
||||
use Git\Repository;
|
||||
use Git\ScopeAware;
|
||||
|
||||
class Tree extends ScopeAware implements \RecursiveIterator
|
||||
{
|
||||
protected $mode;
|
||||
protected $hash;
|
||||
protected $name;
|
||||
protected $data;
|
||||
protected $position = 0;
|
||||
|
||||
public function __construct($hash, Client $client, Repository $repository) {
|
||||
$this->setClient($client);
|
||||
$this->setRepository($repository);
|
||||
$this->setHash($hash);
|
||||
}
|
||||
|
||||
public function parse()
|
||||
{
|
||||
$data = $this->getClient()->run($this->getRepository(), 'ls-tree -l ' . $this->getHash());
|
||||
$lines = explode("\n", $data);
|
||||
$files = array();
|
||||
$root = array();
|
||||
|
||||
foreach ($lines as $key => $line) {
|
||||
if (empty($line)) {
|
||||
unset($lines[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$files[] = preg_split("/[\s]+/", $line);
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
if ($file[1] == 'commit') {
|
||||
// submodule
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($file[0] == '120000') {
|
||||
$show = $this->getClient()->run($this->getRepository(), 'show ' . $file[2]);
|
||||
$tree = new Symlink;
|
||||
$tree->setMode($file[0]);
|
||||
$tree->setName($file[4]);
|
||||
$tree->setPath($show);
|
||||
$root[] = $tree;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($file[1] == 'blob') {
|
||||
$blob = new Blob($file[2], $this->getClient(), $this->getRepository());
|
||||
$blob->setMode($file[0]);
|
||||
$blob->setName($file[4]);
|
||||
$blob->setSize($file[3]);
|
||||
$root[] = $blob;
|
||||
continue;
|
||||
}
|
||||
|
||||
$tree = new Tree($file[2], $this->getClient(), $this->getRepository());
|
||||
$tree->setMode($file[0]);
|
||||
$tree->setName($file[4]);
|
||||
$root[] = $tree;
|
||||
}
|
||||
|
||||
$this->data = $root;
|
||||
}
|
||||
|
||||
public function output()
|
||||
{
|
||||
$files = $folders = array();
|
||||
|
||||
foreach ($this as $node) {
|
||||
if ($node instanceof Blob) {
|
||||
$file['type'] = 'blob';
|
||||
$file['name'] = $node->getName();
|
||||
$file['size'] = $node->getSize();
|
||||
$file['mode'] = $node->getMode();
|
||||
$file['hash'] = $node->getHash();
|
||||
$files[] = $file;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node instanceof Tree) {
|
||||
$folder['type'] = 'folder';
|
||||
$folder['name'] = $node->getName();
|
||||
$folder['size'] = '';
|
||||
$folder['mode'] = $node->getMode();
|
||||
$folder['hash'] = $node->getHash();
|
||||
$folders[] = $folder;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node instanceof Symlink) {
|
||||
$folder['type'] = 'symlink';
|
||||
$folder['name'] = $node->getName();
|
||||
$folder['size'] = '';
|
||||
$folder['mode'] = $node->getMode();
|
||||
$folder['hash'] = '';
|
||||
$folder['path'] = $node->getPath();
|
||||
$folders[] = $folder;
|
||||
}
|
||||
}
|
||||
|
||||
// Little hack to make folders appear before files
|
||||
$files = array_merge($folders, $files);
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
public function valid() {
|
||||
return isset($this->data[$this->position]);
|
||||
}
|
||||
|
||||
public function hasChildren() {
|
||||
return is_array($this->data[$this->position]);
|
||||
}
|
||||
|
||||
public function next() {
|
||||
$this->position++;
|
||||
}
|
||||
|
||||
public function current() {
|
||||
return $this->data[$this->position];
|
||||
}
|
||||
|
||||
public function getChildren() {
|
||||
return $this->data[$this->position];
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
public function key() {
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function getMode()
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
public function setMode($mode)
|
||||
{
|
||||
$this->mode = $mode;
|
||||
}
|
||||
|
||||
public function getHash()
|
||||
{
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
public function setHash($hash)
|
||||
{
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
465
lib/Git/Repository.php
Normal file
465
lib/Git/Repository.php
Normal file
@@ -0,0 +1,465 @@
|
||||
<?php
|
||||
|
||||
namespace Git;
|
||||
|
||||
use Git\Commit\Commit;
|
||||
use Git\Model\Tree;
|
||||
use Git\Model\Blob;
|
||||
use Git\Model\Diff;
|
||||
|
||||
class Repository
|
||||
{
|
||||
protected $path;
|
||||
protected $client;
|
||||
|
||||
public function __construct($path, Client $client)
|
||||
{
|
||||
$this->setPath($path);
|
||||
$this->setClient($client);
|
||||
}
|
||||
|
||||
public function setClient(Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public function getClient()
|
||||
{
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
mkdir($this->getPath());
|
||||
$this->getClient()->run($this, 'init');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getConfig($key)
|
||||
{
|
||||
$key = $this->getClient()->run($this, 'config ' . $key);
|
||||
return trim($key);
|
||||
}
|
||||
|
||||
public function setConfig($key, $value)
|
||||
{
|
||||
$this->getClient()->run($this, "config $key \"$value\"");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add untracked files
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $files Files to be added to the repository
|
||||
*/
|
||||
public function add($files = '.')
|
||||
{
|
||||
if(is_array($files)) {
|
||||
$files = implode(' ', $files);
|
||||
}
|
||||
|
||||
$this->getClient()->run($this, "add $files");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all untracked files
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function addAll()
|
||||
{
|
||||
$this->getClient()->run($this, "add -A");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit changes to the repository
|
||||
*
|
||||
* @access public
|
||||
* @param string $message Description of the changes made
|
||||
*/
|
||||
public function commit($message)
|
||||
{
|
||||
$this->getClient()->run($this, "commit -m '$message'");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkout a branch
|
||||
*
|
||||
* @access public
|
||||
* @param string $branch Branch to be checked out
|
||||
*/
|
||||
public function checkout($branch)
|
||||
{
|
||||
$this->getClient()->run($this, "checkout $branch");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull repository changes
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function pull()
|
||||
{
|
||||
$this->getClient()->run($this, "pull");
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update remote references
|
||||
*
|
||||
* @access public
|
||||
* @param string $repository Repository to be pushed
|
||||
* @param string $refspec Refspec for the push
|
||||
*/
|
||||
public function push($repository = null, $refspec = null)
|
||||
{
|
||||
$command = "push";
|
||||
|
||||
if($repository) {
|
||||
$command .= " $repository";
|
||||
}
|
||||
|
||||
if($refspec) {
|
||||
$command .= " $refspec";
|
||||
}
|
||||
|
||||
$this->getClient()->run($this, $command);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a list of the repository branches
|
||||
*
|
||||
* @access public
|
||||
* @return array List of branches
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
$branches = $this->getClient()->run($this, "branch");
|
||||
$branches = explode("\n", $branches);
|
||||
$branches = array_filter(preg_replace('/[\*\s]/', '', $branches));
|
||||
|
||||
return $branches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the current repository branch
|
||||
*
|
||||
* @access public
|
||||
* @return string Current repository branch
|
||||
*/
|
||||
public function getCurrentBranch()
|
||||
{
|
||||
$branches = $this->getClient()->run($this, "branch");
|
||||
$branches = explode("\n", $branches);
|
||||
|
||||
foreach($branches as $branch) {
|
||||
if($branch[0] == '*') {
|
||||
return substr($branch, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specified branch exists
|
||||
*
|
||||
* @access public
|
||||
* @param string $branch Branch to be checked
|
||||
* @return boolean True if the branch exists
|
||||
*/
|
||||
public function hasBranch($branch)
|
||||
{
|
||||
$branches = $this->getBranches();
|
||||
$status = in_array($branch, $branches);
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new repository branch
|
||||
*
|
||||
* @access public
|
||||
* @param string $branch Branch name
|
||||
*/
|
||||
public function createBranch($branch)
|
||||
{
|
||||
$this->getClient()->run($this, "branch $branch");
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a list of the repository tags
|
||||
*
|
||||
* @access public
|
||||
* @return array List of tags
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
$tags = $this->getClient()->run($this, "tag");
|
||||
$tags = explode("\n", $tags);
|
||||
|
||||
if (empty($tags[0])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the repository commit log
|
||||
*
|
||||
* @access public
|
||||
* @return array Commit log
|
||||
*/
|
||||
public function getCommits($file = null)
|
||||
{
|
||||
$command = 'log --pretty=format:\'"%h": {"hash": "%H", "short_hash": "%h", "tree": "%T", "parent": "%P", "author": "%an", "author_email": "%ae", "date": "%at", "commiter": "%cn", "commiter_email": "%ce", "commiter_date": "%ct", "message": "%f"}\'';
|
||||
|
||||
if ($file) {
|
||||
$command .= " $file";
|
||||
}
|
||||
|
||||
$logs = $this->getClient()->run($this, $command);
|
||||
$logs = str_replace("\n", ',', $logs);
|
||||
$logs = json_decode("{ $logs }", true);
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$log['message'] = str_replace('-', ' ', $log['message']);
|
||||
$commit = new Commit;
|
||||
$commit->importData($log);
|
||||
$commits[] = $commit;
|
||||
}
|
||||
|
||||
return $commits;
|
||||
}
|
||||
|
||||
public function getRelatedCommits($hash)
|
||||
{
|
||||
$logs = $this->getClient()->run($this, 'log --pretty=format:\'"%h": {"hash": "%H", "short_hash": "%h", "tree": "%T", "parent": "%P", "author": "%an", "author_email": "%ae", "date": "%at", "commiter": "%cn", "commiter_email": "%ce", "commiter_date": "%ct", "message": "%f"}\'');
|
||||
$logs = str_replace("\n", ',', $logs);
|
||||
$logs = json_decode("{ $logs }", true);
|
||||
|
||||
foreach ($logs as $log) {
|
||||
$log['message'] = str_replace('-', ' ', $log['message']);
|
||||
$logTree = $this->getClient()->run($this, 'diff-tree -t -r ' . $log['hash']);
|
||||
$lines = explode("\n", $logTree);
|
||||
array_shift($lines);
|
||||
$files = array();
|
||||
|
||||
foreach ($lines as $key => $line) {
|
||||
if (empty($line)) {
|
||||
unset($lines[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$files[] = preg_split("/[\s]+/", $line);
|
||||
}
|
||||
|
||||
// Now let's find the commits who have our hash within them
|
||||
foreach ($files as $file) {
|
||||
if ($file[1] == 'commit') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($file[3] == $hash) {
|
||||
$commit = new Commit;
|
||||
$commit->importData($log);
|
||||
$commits[] = $commit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $commits;
|
||||
}
|
||||
|
||||
public function getCommit($commit)
|
||||
{
|
||||
$logs = $this->getClient()->run($this, 'show --pretty=format:\'{"hash": "%H", "short_hash": "%h", "tree": "%T", "parent": "%P", "author": "%an", "author_email": "%ae", "date": "%at", "commiter": "%cn", "commiter_email": "%ce", "commiter_date": "%ct", "message": "%f"}\' ' . $commit);
|
||||
$logs = explode("\n", $logs);
|
||||
|
||||
// Read commit metadata
|
||||
$data = json_decode($logs[0], true);
|
||||
$data['message'] = str_replace('-', ' ', $data['message']);
|
||||
$commit = new Commit;
|
||||
$commit->importData($data);
|
||||
unset($logs[0]);
|
||||
|
||||
// Read diff logs
|
||||
foreach ($logs as $log) {
|
||||
if ('diff' === substr($log, 0, 4)) {
|
||||
if (isset($diff)) {
|
||||
$diffs[] = $diff;
|
||||
}
|
||||
|
||||
$diff = new Diff;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('index' === substr($log, 0, 5)) {
|
||||
$diff->setIndex($log);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('---' === substr($log, 0, 3)) {
|
||||
$diff->setOld($log);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('+++' === substr($log, 0, 3)) {
|
||||
$diff->setNew($log);
|
||||
continue;
|
||||
}
|
||||
|
||||
$diff->addLine($log);
|
||||
}
|
||||
|
||||
if (isset($diff)) {
|
||||
$diffs[] = $diff;
|
||||
}
|
||||
|
||||
$commit->setDiffs($diffs);
|
||||
|
||||
return $commit;
|
||||
}
|
||||
|
||||
public function getAuthorStatistics()
|
||||
{
|
||||
$logs = $this->getClient()->run($this, 'log --pretty=format:\'%an||%ae\'');
|
||||
$logs = explode("\n", $logs);
|
||||
$logs = array_count_values($logs);
|
||||
arsort($logs);
|
||||
|
||||
foreach ($logs as $user => $count) {
|
||||
$user = explode('||', $user);
|
||||
$data[] = array('name' => $user[0], 'email' => $user[1], 'commits' => $count);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getStatistics($branch)
|
||||
{
|
||||
// Calculate amount of files, extensions and file size
|
||||
$logs = $this->getClient()->run($this, 'ls-tree -r -l ' . $branch);
|
||||
$lines = explode("\n", $logs);
|
||||
$files = array();
|
||||
$data['extensions'] = array();
|
||||
$data['size'] = 0;
|
||||
$data['files'] = 0;
|
||||
|
||||
foreach ($lines as $key => $line) {
|
||||
if (empty($line)) {
|
||||
unset($lines[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$files[] = preg_split("/[\s]+/", $line);
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
if ($file[1] == 'blob') {
|
||||
$data['files']++;
|
||||
}
|
||||
|
||||
if (is_numeric($file[3])) {
|
||||
$data['size'] += $file[3];
|
||||
}
|
||||
|
||||
if (($pos = strrpos($file[4], '.')) !== FALSE) {
|
||||
$data['extensions'][] = substr($file[4], $pos);
|
||||
}
|
||||
}
|
||||
|
||||
$data['extensions'] = array_count_values($data['extensions']);
|
||||
arsort($data['extensions']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Tree for the provided folder
|
||||
*
|
||||
* @param string $tree Folder that will be parsed
|
||||
* @return Tree Instance of Tree for the provided folder
|
||||
*/
|
||||
public function getTree($tree)
|
||||
{
|
||||
$tree = new Tree($tree, $this->getClient(), $this);
|
||||
$tree->parse();
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Blob for the provided file
|
||||
*
|
||||
* @param string $blob File that will be parsed
|
||||
* @return Blob Instance of Blob for the provided file
|
||||
*/
|
||||
public function getBlob($blob)
|
||||
{
|
||||
return new Blob($blob, $this->getClient(), $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blames the provided file and parses the output
|
||||
*
|
||||
* @param string $file File that will be blamed
|
||||
* @return array Commits hashes containing the lines
|
||||
*/
|
||||
public function getBlame($file)
|
||||
{
|
||||
$logs = $this->getClient()->run($this, "blame -s $file");
|
||||
$logs = explode("\n", $logs);
|
||||
|
||||
foreach ($logs as $log) {
|
||||
if ($log == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$split = preg_split("/[a-zA-Z0-9^]{8}[\s]+[0-9]+\)/", $log);
|
||||
preg_match_all("/([a-zA-Z0-9^]{8})[\s]+([0-9]+)\)/", $log, $match);
|
||||
|
||||
$commit = $match[1][0];
|
||||
|
||||
if (!isset($blame[$commit]['line'])) {
|
||||
$blame[$commit]['line'] = '';
|
||||
}
|
||||
|
||||
$blame[$commit]['line'] .= PHP_EOL . $split[1];
|
||||
}
|
||||
|
||||
return $blame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Repository path
|
||||
*
|
||||
* @return string Path where the repository is located
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current Repository path
|
||||
*
|
||||
* @param string $path Path where the repository is located
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
}
|
||||
29
lib/Git/ScopeAware.php
Normal file
29
lib/Git/ScopeAware.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Git;
|
||||
|
||||
class ScopeAware
|
||||
{
|
||||
protected $client;
|
||||
protected $repository;
|
||||
|
||||
public function setClient(Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public function getClient()
|
||||
{
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
public function getRepository()
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
|
||||
public function setRepository($repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user