Files
faveo/vendor/gitonomy/gitlib/src/Gitonomy/Git/Log.php
RafficMohammed da241bacb6 updated-packages
2023-01-08 00:13:22 +05:30

240 lines
5.5 KiB
PHP

<?php
/**
* This file is part of Gitonomy.
*
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
* (c) Julien DIDIER <genzo.wm@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Gitonomy\Git;
use Gitonomy\Git\Diff\Diff;
use Gitonomy\Git\Exception\ProcessException;
use Gitonomy\Git\Exception\ReferenceNotFoundException;
use Gitonomy\Git\Util\StringHelper;
/**
* @author Alexandre Salomé <alexandre.salome@gmail.com>
*/
class Log implements \Countable, \IteratorAggregate
{
/**
* @var Repository
*/
protected $repository;
/**
* @var null|RevisionList
*/
protected $revisions;
/**
* @var array
*/
protected $paths;
/**
* @var int
*/
protected $offset;
/**
* @var int
*/
protected $limit;
/**
* Instanciates a git log object.
*
* @param Repository $repository the repository where log occurs
* @param RevisionList|Revision|array|null $revisions a list of revisions or null if you want all history
* @param array $paths paths to filter on
* @param int|null $offset start list from a given position
* @param int|null $limit limit number of fetched elements
*/
public function __construct(Repository $repository, $revisions = null, $paths = null, $offset = null, $limit = null)
{
if (null !== $revisions && !$revisions instanceof RevisionList) {
$revisions = new RevisionList($repository, $revisions);
}
if (null === $paths) {
$paths = [];
} elseif (is_string($paths)) {
$paths = [$paths];
} elseif (!is_array($paths)) {
throw new \InvalidArgumentException(sprintf('Expected a string or an array, got a "%s".', is_object($paths) ? get_class($paths) : gettype($paths)));
}
$this->repository = $repository;
$this->revisions = $revisions;
$this->paths = $paths;
$this->offset = $offset;
$this->limit = $limit;
}
/**
* @return Diff
*/
public function getDiff()
{
return $this->repository->getDiff($this->revisions);
}
/**
* @return RevisionList
*/
public function getRevisions()
{
return $this->revisions;
}
/**
* @return array
*/
public function getPaths()
{
return $this->paths;
}
/**
* @return int
*/
public function getOffset()
{
return $this->offset;
}
/**
* @param int $offset
*/
public function setOffset($offset)
{
$this->offset = $offset;
return $this;
}
/**
* @return int
*/
public function getLimit()
{
return $this->limit;
}
/**
* @param int $limit
*/
public function setLimit($limit)
{
$this->limit = $limit;
return $this;
}
/**
* @return Commit
*/
public function getSingleCommit()
{
$limit = $this->limit;
$this->limit = 1;
$commits = $this->getCommits();
$this->setLimit($limit);
if (count($commits) === 0) {
throw new ReferenceNotFoundException('The log is empty');
}
return array_pop($commits);
}
/**
* @return Commit[]
*/
public function getCommits()
{
$args = ['--encoding='.StringHelper::getEncoding(), '--format=raw'];
if (null !== $this->offset) {
$args[] = '--skip='.((int) $this->offset);
}
if (null !== $this->limit) {
$args[] = '-n';
$args[] = (int) $this->limit;
}
if (null !== $this->revisions) {
$args = array_merge($args, $this->revisions->getAsTextArray());
} else {
$args[] = '--all';
}
$args[] = '--';
$args = array_merge($args, $this->paths);
try {
$output = $this->repository->run('log', $args);
} catch (ProcessException $e) {
throw new ReferenceNotFoundException(sprintf('Can not find revision "%s"', implode(' ', $this->revisions->getAsTextArray())), null, $e);
}
$parser = new Parser\LogParser();
$parser->parse($output);
$result = [];
foreach ($parser->log as $commitData) {
$hash = $commitData['id'];
unset($commitData['id']);
$commit = $this->repository->getCommit($hash);
$commit->setData($commitData);
$result[] = $commit;
}
return $result;
}
/**
* @see Countable
*/
#[\ReturnTypeWillChange]
public function count()
{
return $this->countCommits();
}
/**
* @see IteratorAggregate
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new \ArrayIterator($this->getCommits());
}
/**
* Count commits, without offset or limit.
*
* @return int
*/
public function countCommits()
{
if (null !== $this->revisions && count($this->revisions)) {
$output = $this->repository->run('rev-list', array_merge(['--count'], $this->revisions->getAsTextArray(), ['--'], $this->paths));
} else {
$output = $this->repository->run('rev-list', array_merge(['--count', '--all', '--'], $this->paths));
}
return (int) $output;
}
}