3029b46fbf6604342f7d6aea8269bf35f917125d
[phpgit.git] / library / Git / Commit.php
blob3029b46fbf6604342f7d6aea8269bf35f917125d
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 continue;
35 $this->$k = $v;
39 // __bake__
41 /**
42 * Return a shortened representation of Git's commit ID.
44 public function idAbbrev() {
45 return substr($this->id, 0, 7);
48 // public static(?) function count() {
49 // public static function findAll($repo, $ref, $kwargs) {
51 /**
52 * Parses out commit information from git log --pretty raw into an
53 * array of Commit objects.
54 * @param $repo Git_Repo
55 * @param $text Text from command
56 * @return Array of Git_Commit objects
58 public static function listFromString($repo, $text) {
59 $lines = explode("\n", $text);
60 foreach ($lines as $k => $v) if (trim($v) === '') unset($lines[$k]);
61 $lines = array_values($lines);
63 for ($i = 0, $c = count($lines); $i < $c;) {
65 $id = self::_l($lines, $i, true);
66 $tree = self::_l($lines, $i, true);
68 $parents = array();
69 while ($i < $c && strncmp($lines[$i], 'parent', 6) === 0) {
70 $parents[] = self::_l($lines, $i, true);
72 list($author, $authoredDate) = self::actor(self::_l($lines, $i));
73 list($committer, $committedDate) = self::actor(self::_l($lines, $i));
75 $messages = array();
76 while ($i < $c && strncmp($lines[$i], ' ', 4) === 0) {
77 $messages[] = trim(self::_l($lines, $i));
80 $message = $messages ? $messages[0] : '';
82 $commits[] = new Git_Commit($repo, compact(
83 'id', 'parents', 'tree', 'author', 'authoredDate',
84 'committer', 'committedDate', 'message'
85 ));
87 return $commits;
90 /**
91 * Grabs the current line, advances the index forward, and parses
92 * out the last bit.
93 * @param $lines Array of lines
94 * @param &$i Index in $lines array
95 * @param $grab_last Whether or not to retrieve the span of text after
96 * the last whitespace.
98 private static function _l($lines, &$i, $grab_last = false) {
99 $line = $lines[$i++];
100 if ($grab_last) {
101 $line = trim($line);
102 $line = substr($line, strrpos($line, ' ') + 1);
104 return $line;
108 * Parse out actor (author/committer) information.
109 * @returns array('Actor name <email>', timestamp)
111 public static function actor($line) {
112 preg_match('/^.+? (.*) (\d+) .*$/', $line, $matches);
113 list($x, $actor, $epoch) = $matches;
114 return array(Git_Actor::fromString($actor), new DateTime($epoch));