started with commitdiff page
[phpgitweb.git] / htdocs / lib / GitCommand.class.php
index c06e0fb4298fe120c39370e079d03ffa28890fb2..a8ede915817beaafc0e070ddcb8027248bd8ae2a 100644 (file)
@@ -138,6 +138,36 @@ class GitCommand {
                return null;
        }
        
+       private static function parse_difftree($line) {
+               $entry = array();
+               if(preg_match('/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/i', $line, $matches)) {
+                       $entry['parents'] = 1;
+                       $entry['from_mode'] = $matches[1];
+                       $entry['to_mode'] = $matches[2];
+                       $entry['from_id'] = $matches[3];
+                       $entry['to_id'] = $matches[4];
+                       $entry['status'] = $matches[5];
+                       $entry['similarity'] = $matches[6];
+                       $entry['file'] = $matches[7];
+                       if($entry['status'] == 'R' || $entry['status'] == 'C') { //renamed or copied
+                               $files = explode("\t", $entry['file']);
+                               $entry['from_file'] = $files[0];
+                               $entry['to_file'] = $files[1];
+                       }
+               } else if(preg_match('/^(::+)((?:[0-7]{6} )+)((?:[0-9a-fA-F]{40} )+)([a-zA-Z]+)\t(.*)$/i', $line, $matches)) {
+                       $entry['parents'] = strlen($matches[1]);
+                       $from_modes = explode(" ", $matches[2]);
+                       $entry['from_mode'] = array_slice($from_modes, 1);
+                       $entry['to_mode'] = $from_modes[0];
+                       $from_ids = explode(" ", $matches[3]);
+                       $entry['from_id'] = array_slice($from_ids, 1);
+                       $entry['to_id'] = $from_ids[0];
+                       $entry['status'] = str_split($matches[4]);
+                       $entry['file'] = $matches[5];
+               }
+               return $entry;
+       }
+       
        public static function get_commit_changes($git_path, $commit_id, $parents) {
                $args = array("diff-tree", "-r", "--no-commit-id");
                switch(GitConfig::DETECT_RENAME_LEVEL) {
@@ -167,35 +197,57 @@ class GitCommand {
                foreach(explode("\n", $result) as $line) {
                        if($line == "")
                                continue;
-                       $entry = array();
-                       if(preg_match('/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/i', $line, $matches)) {
-                               $entry['parents'] = 1;
-                               $entry['from_mode'] = $matches[1];
-                               $entry['to_mode'] = $matches[2];
-                               $entry['from_id'] = $matches[3];
-                               $entry['to_id'] = $matches[4];
-                               $entry['status'] = $matches[5];
-                               $entry['similarity'] = $matches[6];
-                               $entry['file'] = $matches[7];
-                               if($entry['status'] == 'R' || $entry['status'] == 'C') { //renamed or copied
-                                       $files = explode("\t", $entry['file']);
-                                       $entry['from_file'] = $files[0];
-                                       $entry['to_file'] = $files[1];
-                               }
-                       } else if(preg_match('/^(::+)((?:[0-7]{6} )+)((?:[0-9a-fA-F]{40} )+)([a-zA-Z]+)\t(.*)$/i', $line, $matches)) {
-                               $entry['parents'] = strlen($matches[1]);
-                               $from_modes = explode(" ", $matches[2]);
-                               $entry['from_mode'] = array_slice($from_modes, 1);
-                               $entry['to_mode'] = $from_modes[0];
-                               $from_ids = explode(" ", $matches[3]);
-                               $entry['from_id'] = array_slice($from_ids, 1);
-                               $entry['to_id'] = $from_ids[0];
-                               $entry['status'] = str_split($matches[4]);
-                               $entry['file'] = $matches[5];
-                       }
-                       $tree[] = $entry;
+                       $tree[] = self::parse_difftree($line);
                }
                return $tree;
        }
        
+       public static function get_commit_diff($git_path, $commit_id, $parents) {
+               $args = array("diff-tree", "-r", "--no-commit-id", "--patch-with-raw", "--full-index");
+               switch(GitConfig::DETECT_RENAME_LEVEL) {
+               case 0:
+                       $args[] = "-M";
+                       break;
+               case 1:
+                       $args[] = "-C";
+                       break;
+               case 2:
+                       $args[] = "-C";
+                       $args[] = "--find-copies-harder";
+                       break;
+               }
+               if(GitConfig::DETECT_REWRITES)
+                       $args[] = "-B";
+               if(is_array($parents) && count($parents) > 1)
+                       $args[] = "--cc";
+               else if(is_array($parents) && count($parents) == 1)
+                       $args[] = $parents[0];
+               else
+                       $args[] = "--root";
+               $args[] = $commit_id;
+               $args[] = "--";
+               $result = self::git_execute($args, $git_path);
+               $tree = array();
+               $diffs = array();
+               $diff = null;
+               $parse_difftree = true;
+               foreach(explode("\n", $result) as $line) {
+                       if($line == "" && $parse_difftree)
+                               $parse_difftree = false;
+                       else if($parse_difftree)
+                               $tree[] = self::parse_difftree($line);
+                       else {
+                               if(preg_match('/^diff/i', $line)) {
+                                       if($diff)
+                                               $diffs[] = $diff;
+                                       $diff = array();
+                               }
+                               $diff[] = $line;
+                       }
+               }
+               if($diff)
+                       $diffs[] = $diff;
+               $diff_data['tree'] = $tree;
+               return array('tree' => $tree, 'diffs' => $diffs);
+       }
 }