+ public static function get_commit_changes($git_path, $commit_id, $parents) {
+ $args = array("diff-tree", "-r", "--no-commit-id");
+ 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[] = "-c";
+ 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();
+ 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;
+ }
+ return $tree;
+ }
+