nextcloud/3rdparty/granite/git/commit.php

233 lines
5.5 KiB
PHP

<?php
/**
* Commit - provides a 'commit' object
*
* PHP version 5.3
*
* @category Git
* @package Granite
* @author Craig Roberts <craig0990@googlemail.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT Expat License
* @link http://craig0990.github.com/Granite/
*/
namespace Granite\Git;
use \Granite\Git\Object\Raw as Raw;
use \InvalidArgumentException as InvalidArgumentException;
/**
* Commit represents a full commit object
*
* @category Git
* @package Granite
* @author Craig Roberts <craig0990@googlemail.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT Expat License
* @link http://craig0990.github.com/Granite/
*/
class Commit
{
/**
* The path to the repository root
*/
private $path;
/**
* The SHA-1 id of the requested commit
*/
private $sha;
/**
* The size of the commit in bytes
*/
private $size;
/**
* The commit message
*/
private $message;
/**
* The full committer string
*/
private $committer;
/**
* The full author string
*/
private $author;
/**
* The SHA-1 ids of the parent commits
*/
private $parents = array();
/**
* Fetches a raw Git object and parses the result. Throws an
* InvalidArgumentException if the object is not of the correct type,
* or cannot be found.
*
* @param string $path The path to the repository root
* @param string $sha The SHA-1 id of the requested object
*
* @throws InvalidArgumentException
*/
public function __construct($path, $sha = NULL)
{
$this->path = $path;
if ($sha !== NULL) {
$this->sha = $sha;
$object = Raw::factory($path, $sha);
$this->size = $object->size();
if ($object->type() !== Raw::OBJ_COMMIT) {
throw new InvalidArgumentException(
"The object $sha is not a commit, type is " . $object->type()
);
}
// Parse headers and commit message (delimited with "\n\n")
list($headers, $this->message) = explode("\n\n", $object->content(), 2);
$headers = explode("\n", $headers);
foreach ($headers as $header) {
list($header, $value) = explode(' ', $header, 2);
if ($header == 'parent') {
$this->parents[] = $value;
} else {
$this->$header = $value;
}
}
$this->tree = new Tree($this->path, $this->tree);
}
}
/**
* Returns the message stored in the commit
*
* @return string The commit message
*/
public function message($message = NULL)
{
if ($message !== NULL) {
$this->message = $message;
return $this;
}
return $this->message;
}
/**
* Returns the commiter string
*
* @return string The committer string
*/
public function committer($committer = NULL)
{
if ($committer !== NULL) {
$this->committer = $committer;
return $this;
}
return $this->committer;
}
/**
* Returns the author string
*
* @return string The author string
*/
public function author($author = NULL)
{
if ($author !== NULL) {
$this->author = $author;
return $this;
}
return $this->author;
}
/**
* Returns the parents of the commit, or an empty array if none
*
* @return array The parents of the commit
*/
public function parents($parents = NULL)
{
if ($parents !== NULL) {
$this->parents = $parents;
return $this;
}
return $this->parents;
}
/**
* Returns a tree object associated with the commit
*
* @return Tree
*/
public function tree(Tree $tree = NULL)
{
if ($tree !== NULL) {
$this->tree = $tree;
return $this;
}
return $this->tree;
}
/**
* Returns the size of the commit in bytes (Git header + data)
*
* @return int
*/
public function size()
{
return $this->size;
}
/**
* Returns the size of the commit in bytes (Git header + data)
*
* @return int
*/
public function sha()
{
$this->sha = hash('sha1', $this->_raw());
return $this->sha;
}
public function write()
{
$sha = $this->sha();
$path = $this->path
. 'objects'
. DIRECTORY_SEPARATOR
. substr($sha, 0, 2)
. DIRECTORY_SEPARATOR
. substr($sha, 2);
// FIXME: currently writes loose objects only
if (file_exists($path)) {
return FALSE;
}
if (!is_dir(dirname($path))) {
mkdir(dirname($path), 0777, TRUE);
}
$loose = fopen($path, 'wb');
$data = $this->_raw();
$write = fwrite($loose, gzcompress($data));
fclose($loose);
return ($write !== FALSE);
}
public function _raw()
{
$data = 'tree ' . $this->tree->sha() . "\n";
foreach ($this->parents as $parent)
{
$data .= "parent $parent\n";
}
$data .= 'author ' . $this->author . "\n";
$data .= 'committer ' . $this->committer . "\n\n";
$data .= $this->message;
$data = 'commit ' . strlen($data) . "\0" . $data;
return $data;
}
}