Fix up Git_Repo->log() to actually work.
[phpgit.git] / library / Git / Commit.php
blob967feb6dc6a671556251e9f18c54579f356b17b5
1 <?php
3 /**
4 * Represents a commit in the Git repository.
5 */
6 class Git_Commit {
8 public $repo, $id, $tree, $author, $authoredDate, $committer,
9 $committedDate, $message, $parents = array();
11 /**
12 * @param $repo Git_Repo of this commit.
13 * @param $kwargs Hash of info about this commit, specifically:
14 * 'id' => Id of commit
15 * 'parents' => List of commit IDs (converted to Git_Commit objects)
16 * 'tree' => Tree ID (converted to Git_Tree object)
17 * 'author' => Author string
18 * 'authoredDate' => Authored DateTime
19 * 'committer' => Committer string
20 * 'committedDate' => Committed DateTime
21 * 'message' => First line of commit message
23 public function __construct($repo, $kwargs) {
24 $this->repo = $repo;
25 foreach ($kwargs as $k => $v) {
26 if ($k == 'parents') {
27 foreach ($v as $id) {
28 $this->parents[] = new Git_Commit($repo, array('id' => $id));
30 continue;
31 } elseif ($k == 'tree') {
32 //$this->tree = new Git_Tree($repo, array('id' => $v));
33 // :TODO: Implement Git_Tree
34 $this->tree = $v;
35 continue;
37 $this->$k = $v;
41 // __bake__
43 /**
44 * Return a shortened representation of Git's commit ID.
46 public function idAbbrev() {
47 return substr($this->id, 0, 7);
50 // public static(?) function count() {
51 // public static function findAll($repo, $ref, $kwargs) {
53 /**
54 * Parses out commit information from git log --pretty raw into an
55 * array of Commit objects.
56 * @param $repo Git_Repo
57 * @param $text Text from command
58 * @return Array of Git_Commit objects
60 public static function listFromString($repo, $text) {
61 $lines = explode("\n", $text);
62 foreach ($lines as $k => $v) if (trim($v) === '') unset($lines[$k]);
63 $lines = array_values($lines);
65 for ($i = 0, $c = count($lines); $i < $c;) {
67 $id = self::_l($lines, $i, true);
68 $tree = self::_l($lines, $i, true);
70 $parents = array();
71 while ($i < $c && strncmp($lines[$i], 'parent', 6) === 0) {
72 $parents[] = self::_l($lines, $i, true);
74 list($author, $authoredDate) = self::actor(self::_l($lines, $i));
75 list($committer, $committedDate) = self::actor(self::_l($lines, $i));
77 $messages = array();
78 while ($i < $c && strncmp($lines[$i], ' ', 4) === 0) {
79 $messages[] = trim(self::_l($lines, $i));
82 $message = $messages ? $messages[0] : '';
84 $commits[] = new Git_Commit($repo, compact(
85 'id', 'parents', 'tree', 'author', 'authoredDate',
86 'committer', 'committedDate', 'message'
87 ));
89 return $commits;
92 /**
93 * Grabs the current line, advances the index forward, and parses
94 * out the last bit.
95 * @param $lines Array of lines
96 * @param &$i Index in $lines array
97 * @param $grab_last Whether or not to retrieve the span of text after
98 * the last whitespace.
100 private static function _l($lines, &$i, $grab_last = false) {
101 $line = $lines[$i++];
102 if ($grab_last) {
103 $line = trim($line);
104 $line = substr($line, strrpos($line, ' ') + 1);
106 return $line;
110 * Parse out actor (author/committer) information.
111 * @returns array('Actor name <email>', timestamp)
113 public static function actor($line) {
114 preg_match('/^.+? (.*) (\d+) .*$/', $line, $matches);
115 list($x, $actor, $epoch) = $matches;
116 return array(Git_Actor::fromString($actor), new DateTime($epoch));