0,0 → 1,164 |
<?php |
|
/* |
* Copyright (C) 2008, 2009 Patrik Fimml |
* Copyright (c) 2023 Daniel Marschall |
* |
* This file is part of glip. |
* |
* glip is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 2 of the License, or |
* (at your option) any later version. |
|
* glip is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with glip. If not, see <http://www.gnu.org/licenses/>. |
*/ |
|
namespace ViaThinkSoft\Glip; |
|
class GitCommit extends GitObject |
{ |
/** |
* @brief (string) The tree referenced by this commit, as binary sha1 |
* string. |
*/ |
public $tree; |
|
/** |
* @brief (array of string) Parent commits of this commit, as binary sha1 |
* strings. |
*/ |
public $parents; |
|
/** |
* @brief (GitCommitStamp) The author of this commit. |
*/ |
public $author; |
|
/** |
* @brief (GitCommitStamp) The committer of this commit. |
*/ |
public $committer; |
|
/** |
* @brief (string) Commit summary, i.e. the first line of the commit message. |
*/ |
public $summary; |
|
/** |
* @brief (string) Everything after the first line of the commit message. |
*/ |
public $detail; |
|
public $history; |
|
public function __construct($repo) { |
parent::__construct($repo, Git::OBJ_COMMIT); |
} |
|
public function _unserialize($data) { |
$lines = explode("\n", $data); |
unset($data); |
$meta = array('parent' => array()); |
while (($line = array_shift($lines)) != '') { |
$parts = explode(' ', $line, 2); |
if (!isset($meta[$parts[0]])) |
$meta[$parts[0]] = array($parts[1]); |
else |
$meta[$parts[0]][] = $parts[1]; |
} |
|
$this->tree = pack('H40', $meta['tree'][0]); |
$this->parents = array_map(function ($hex) { |
return pack('H40', $hex); |
}, $meta['parent']); |
$this->author = new GitCommitStamp; |
$this->author->unserialize($meta['author'][0]); |
$this->committer = new GitCommitStamp; |
$this->committer->unserialize($meta['committer'][0]); |
|
$this->summary = array_shift($lines); |
$this->detail = implode("\n", $lines); |
|
$this->history = null; |
} |
|
public function _serialize() { |
$s = ''; |
$s .= sprintf("tree %s\n", bin2hex($this->tree)); |
foreach ($this->parents as $parent) |
$s .= sprintf("parent %s\n", bin2hex($parent)); |
$s .= sprintf("author %s\n", $this->author->serialize()); |
$s .= sprintf("committer %s\n", $this->committer->serialize()); |
$s .= "\n" . $this->summary . "\n" . $this->detail; |
return $s; |
} |
|
/** |
* @brief Get commit history in topological order. |
* |
* @returns (array of GitCommit) |
*/ |
public function getHistory() { |
if ($this->history) |
return $this->history; |
|
/* count incoming edges */ |
$inc = array(); |
|
$queue = array($this); |
while (($commit = array_shift($queue)) !== null) { |
foreach ($commit->parents as $parent) { |
if (!isset($inc[$parent])) { |
$inc[$parent] = 1; |
$queue[] = $this->repo->getObject($parent); |
} else |
$inc[$parent]++; |
} |
} |
|
$queue = array($this); |
$r = array(); |
while (($commit = array_pop($queue)) !== null) { |
array_unshift($r, $commit); |
foreach ($commit->parents as $parent) { |
if (--$inc[$parent] == 0) |
$queue[] = $this->repo->getObject($parent); |
} |
} |
|
$this->history = $r; |
return $r; |
} |
|
/** |
* @brief Get the tree referenced by this commit. |
* |
* @returns GitTree The GitTree referenced by this commit. |
*/ |
public function getTree() { |
return $this->repo->getObject($this->tree); |
} |
|
/** |
* @copybrief GitTree::find() |
* |
* This is a convenience function calling GitTree::find() on the commit's |
* tree. |
* |
* @copydetails GitTree::find() |
*/ |
public function find($path) { |
return $this->getTree()->find($path); |
} |
|
static public function treeDiff($a, $b) { |
return GitTree::treeDiff($a ? $a->getTree() : null, $b ? $b->getTree() : null); |
} |
} |