continued :)
[phpgitweb.git] / htdocs / lib / GitCommand.class.php
diff --git a/htdocs/lib/GitCommand.class.php b/htdocs/lib/GitCommand.class.php
new file mode 100644 (file)
index 0000000..4e20281
--- /dev/null
@@ -0,0 +1,119 @@
+<?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;
+       }
+       
+}