3 final class PhabricatorGitGraphStream
4 extends PhabricatorRepositoryGraphStream
{
10 private $parents = array();
11 private $dates = array();
13 public function __construct(
14 PhabricatorRepository
$repository,
15 $start_commit = null) {
17 $this->repository
= $repository;
18 $this->startCommit
= $start_commit;
20 if ($start_commit !== null) {
21 $future = $repository->getLocalCommandFuture(
23 '--format=%H%x01%P%x01%ct',
24 gitsprintf('%s', $start_commit));
26 $future = $repository->getLocalCommandFuture(
28 '--format=%H%x01%P%x01%ct');
31 $this->iterator
= new LinesOfALargeExecFuture($future);
32 $this->iterator
->setDelimiter("\n");
33 $this->iterator
->rewind();
36 public function getParents($commit) {
37 if (!isset($this->parents
[$commit])) {
38 $this->parseUntil($commit);
40 $parents = $this->parents
[$commit];
42 // NOTE: In Git, it is possible for a commit to list the same parent more
43 // than once. See T5226. Discard duplicate parents.
45 return array_unique($parents);
48 public function getCommitDate($commit) {
49 if (!isset($this->dates
[$commit])) {
50 $this->parseUntil($commit);
52 return $this->dates
[$commit];
55 private function parseUntil($commit) {
56 if ($this->isParsed($commit)) {
60 $gitlog = $this->iterator
;
62 while ($gitlog->valid()) {
63 $line = $gitlog->current();
70 list($hash, $parents, $epoch) = explode("\1", $line);
73 $parents = explode(' ', $parents);
79 $this->dates
[$hash] = $epoch;
80 $this->parents
[$hash] = $parents;
82 if ($this->isParsed($commit)) {
87 if ($this->startCommit
!== null) {
90 'Commit "%s" is not a reachable ancestor of "%s".',
96 'Commit "%s" is not a reachable ancestor of any ref.',
101 private function isParsed($commit) {
102 return isset($this->dates
[$commit]);