Initial commit; implement enough code to get Git_Repo->log() semi-working.
[phpgit.git] / library / Git / Commit.php
blob1bd8fcf2668ab6c85b03f9cc7d6a63dca7779a2d
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 for ($i = 0, $c = count($lines); $i < $c; $i++) {
64 $id = self::_l($lines, $i, true);
65 $tree = self::_l($lines, $i, true);
67 $parents = array();
68 while ($lines && strncmp($lines[$i], 'parent', 6) === 0) {
69 $parents[] = self::_l($lines, $i, true);
71 list($author, $authoredDate) = self::actor(self::_l($lines, $i));
72 list($committer, $committedDate) = self::actor(self::_l($lines, $i));
74 $messages = array();
75 while ($lines && strncmp($lines[$i], ' ', 4) === 0) {
76 $messages[] = trim(self::_l($lines, $i));
79 $message = $messages ? $messages[0] : '';
81 $commits[] = new Git_Commit($repo, compact(
82 'id', 'parents', 'tree', 'author', 'authoredDate',
83 'committer', 'committedDate', 'message'
84 ));
86 return $commits;
89 /**
90 * Grabs the current line, advances the index forward, and parses
91 * out the last bit.
92 * @param $lines Array of lines
93 * @param &$i Index in $lines array
94 * @param $grab_last Whether or not to retrieve the span of text after
95 * the last whitespace.
97 private static function _l($lines, &$i, $grab_last = false) {
98 $line = $lines[$i++];
99 if ($grab_last) {
100 $line = trim($line);
101 $line = substr($line, strrpos($line, ' ') + 1);
103 return $line;
107 * Parse out actor (author/committer) information.
108 * @returns array('Actor name <email>', timestamp)
110 public static function actor($line) {
111 preg_match('/^.+? (.*) (\d+) .*$/', $line, $matches);
112 list($x, $actor, $epoch) = $matches;
113 return array(Git_Actor::fromString($actor), new DateTime($epoch));