+<?php
+/* GitCommand.class.php - phpgitweb
+ * Copyright (C) 2011-2012 Philipp Kreil (pk910)
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class GitCommand {
+ private static $git = null;
+ private static $counter = 0;
+
+ private static function command_header($git_path = null) {
+ if(!self::$git) {
+ //find git executable
+ if(GitConfig::GIT_EXEC)
+ self::$git = GitConfig::GIT_EXEC;
+ else
+ self::$git = str_replace(array("\n", "\r"), array("", ""), `which git`);
+ if(!self::$git) {
+ trigger_error("Can not find git executable.", E_USER_ERROR);
+ self::$git = "git";
+ }
+ }
+ $command = self::$git;
+ if($git_path)
+ $command .= " --git-dir=".$git_path;
+ return $command;
+ }
+
+ private static function execute($command) {
+ $result = array();
+ exec($command, $result);
+ self::$counter++;
+ return implode("\n", $result);
+ }
+
+ public static function core_version() {
+ $command = self::command_header();
+ if(!$command)
+ return null;
+ $command .= " --version";
+ $version = self::execute($command);
+ preg_match("/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/i", $version, $result);
+ return $result[0];
+ }
+
+ public static function last_activity($git_path, $ref = null) {
+ $command = self::command_header($git_path);
+ if(!$command)
+ return null;
+ $command .= " for-each-ref --format=%\(committer\) --sort=-committerdate --count=1";
+ if($ref)
+ $command .= " ".$ref;
+ $age = self::execute($command);
+ preg_match("/[0-9]{9,}/i", $age, $result);
+ return $result[0];
+ }
+
+ private static function parse_commit($commit_data) {
+ $commit = array();
+ $rev_lines = explode("\n", str_replace("\r", "", $commit_data));
+ $commit['id'] = $rev_lines[0];
+ foreach($rev_lines as $rev_line) {
+ if(substr($rev_line, 0, 4) == " ") {
+ if(array_key_exists('text', $commit))
+ $commit['text'] .= "\n";
+ else
+ $commit['text'] = '';
+ $commit['text'] .= substr($rev_line, 4);
+ } else {
+ $opt = explode(" ", $rev_line, 2);
+ if($opt[0] == "tree")
+ $commit['tree'] = $opt[1];
+ else if($opt[0] == "parent")
+ $commit['parent'][] = $opt[1];
+ else if($opt[0] == "author") {
+ preg_match('/(.*) <([^>]*)> ([0-9]*) [+-0-9]*/i', $opt[1], $matches);
+ $commit['author'] = $matches[1];
+ $commit['author_mail'] = $matches[2];
+ $commit['author_time'] = $matches[3];
+ } else if($opt[0] == "committer") {
+ preg_match('/(.*) <([^>]*)> ([0-9]*) [+-0-9]*/i', $opt[1], $matches);
+ $commit['committer'] = $matches[1];
+ $commit['committer_mail'] = $matches[2];
+ $commit['committer_time'] = $matches[3];
+ }
+ }
+ }
+ return $commit;
+ }
+
+ public static function get_commits($git_path, $head, $maxcount, $skip, $file = null) {
+ $command = self::command_header($git_path);
+ if(!$command)
+ return null;
+ $command .= " rev-list --header --max-count=".$maxcount." --skip=".$skip." ".($head ? $head : "--all")." --";
+ if($file)
+ $command .= " ".$file;
+ $commit_list = self::execute($command);
+ $commits = array();
+ foreach(explode("\000", $commit_list) as $commit) {
+ if($commit)
+ $commits[] = self::parse_commit($commit);
+ }
+ return $commits;
+ }
+
+}