. */ class difftree { private $difftree_data = null; public function push_difftree_data($data) { $this->difftree_data = $data; } public function generate_difftree($project, $commit, $patch_link) { $difftree = new ContentProvider('commit', 'difftree'); if($this->difftree_data) $tree = $this->difftree_data; else $tree = GitCommand::get_commit_changes($project['path'], $commit['id'], $commit['parent']); $entry_count = 0; if(count($commit['parent']) > 1) $difftree->set('class', ' combined'); else $difftree->set('class', ''); $difftree->set('tree_count', ''); foreach($tree as $entry) { $entry_count++; $difftree->append('tree', $this->tree_entry($entry_count, (($entry_count % 2) ? 'dark' : 'light'), $commit, $entry, $patch_link)); } if($entry_count == 0) $difftree->set('tree', ''); else if($entry_count > 10) $difftree->set('tree_count', new ContentProvider('commit', 'tree_count', array('count' => $entry_count))); return $difftree; } private function tree_entry($diffid, $class, $commit, $entry, $patch_link) { $tree = new ContentProvider('commit', 'tree'); $tree->set('class', $class); $tree->set('hash', $commit['id']); $tree->set('file', $entry['file']); $tree->set('file_hash', $entry['to_id']); if(count($commit['parent']) > 1) { if(preg_match('/^[0]{40}$/', $entry['to_id'])) //file doesn't exist in the result (child) commit $tree->set('file', $entry['file']); else $tree->set('file', new ContentProvider('commit', 'tree_file_link', array('file' => $entry['file'], 'file_hash' => $entry['to_id']))); $tree->set('specials', ''); if($patch_link) $tree->append('merge', new ContentProvider('commit', 'tree_merge_patch_link', array("patch_marker" => "patch".$diffid))); $has_history = false; $not_deleted = false; for($i = 0; $i < count($commit['parent']); $i++) { $status = $entry['status'][$i]; $merge = null; $has_history = ($has_history || ($status != 'A')); $not_deleted = ($not_deleted || ($status != 'D')); switch($status) { case 'A': //Added $merge = new ContentProvider('commit', 'tree_merge_new'); break; case 'D': //Deleted $merge = new ContentProvider('commit', 'tree_merge'); $merge->set('class', ''); $blob_link = new ContentProvider('commit', 'tree_merge_blob', array('hash' => $commit['parent'][$i], 'file' => $entry['file'], 'file_hash' => $entry['to_id'])); $merge->set('links', array($blob_link, ' | ')); break; default: $merge = new ContentProvider('commit', 'tree_merge'); if($entry['from_id'][$i] == $entry['to_id']) { $merge->set('class', ' nochange'); $merge->set('links', ' | '); } else { $merge->set('class', ''); $params = array( 'hash' => $commit['id'], 'parent' => $commit['parent'][$i], 'file' => $entry['file'], 'file_hash' => $entry['to_id'], 'parent_file_hash' => $entry['from_id'][$i], 'id' => ($i + 1) ); $merge->set('links', new ContentProvider('commit', 'tree_merge_diff', $params)); } } $tree->append('merge', $merge); } $tree->set('links', ''); if($not_deleted) { $tree->append('links', new ContentProvider('commit', 'tree_merge_blob', array('hash' => $commit['id'], 'file' => $entry['file'], 'file_hash' => $entry['to_id']))); if($has_history) $tree->append('links', ' | '); } if($has_history) $tree->append('links', new ContentProvider('commit', 'tree_merge_history', array('hash' => $commit['id'], 'file' => $entry['file'], 'file_hash' => $entry['to_id']))); } else { $tree->set('file', new ContentProvider('commit', 'tree_file_link', array('file' => $entry['to_file'], 'file_hash' => $entry['to_id']))); $tree->set('merge', ''); $from_type = Tools::get_filetype($entry['from_mode']); $to_type = Tools::get_filetype($entry['to_mode']); $from_mode = (Tools::is_regular_file($entry['from_mode']) ? Tools::get_file_permissions($entry['from_mode']) : null); $to_mode = (Tools::is_regular_file($entry['to_mode']) ? Tools::get_file_permissions($entry['to_mode']) : null); $link_placeholders = array( "hash" => $commit['id'], "file" => $entry['file'], "file_hash" => $entry['to_id'], "parent_file_hash" => $entry['from_id'], "parent" => (count($commit['parent']) ? $commit['parent'][0] : ""), ); if($patch_link) $tree->append('links', new ContentProvider('commit', 'tree_patch_link', array("patch_marker" => "patch".$diffid))); switch($entry['status']) { case 'A': //Added $tree->set('specials', new ContentProvider('commit', (Tools::is_regular_file($entry['to_mode']) ? 'tree_new_file' : 'tree_new'), array('type' => $to_type, 'mode' => $to_mode))); $tree->append('links', new ContentProvider('commit', 'tree_new_links', $link_placeholders)); break; case 'D': //Deleted $tree->set('specials', new ContentProvider('commit', 'tree_deleted', array('type' => $from_type))); $tree->append('links', new ContentProvider('commit', 'tree_deleted_links', $link_placeholders)); break; case 'M': //Modified case 'T': //Type changed if($entry['from_mode'] != $entry['to_mode']) { $modified = new ContentProvider('commit', 'tree_changed'); $tree->set('specials', $modified); if($from_type != $to_type) $modified->append('changes', new ContentProvider('commit', 'tree_changed_type', array('from' => $from_type, 'to' => $to_type))); if($from_mode != $to_mode && $to_mode) { if($from_mode) $modified->append('changes', new ContentProvider('commit', 'tree_changed_mode', array('from' => $from_mode, 'to' => $to_mode))); else $modified->append('changes', new ContentProvider('commit', 'tree_changed_mode_to', array('to' => $to_mode))); } } else $tree->set('specials', ''); if(!$patch_link && $entry['from_id'] != $entry['to_id']) $tree->append('links', new ContentProvider('commit', 'tree_changed_links_diff', $link_placeholders)); $tree->append('links', new ContentProvider('commit', 'tree_changed_links', $link_placeholders)); break; case 'R': //Renamed case 'C': //Copied $actions = array('R' => 'tree_moved', 'C' => 'tree_copied'); $move = new ContentProvider('commit', $actions[$entry['status']]); $tree->set('specials', $move); $move->set('file', $entry['from_file']); $move->set('file_hash', $entry['to_id']); $move->set('hash', $commit['parent'][0]); $move->set('similarity', $entry['similarity']); if($from_mode != $to_mode) $move->set('mode', new ContentProvider('commit', 'tree_moved_mode', array('mode' => $to_mode))); else $move->set('mode', ''); if($entry['from_id'] != $entry['to_id']) $tree->append('links', new ContentProvider('commit', 'tree_moved_links_diff', $link_placeholders)); $tree->append('links', new ContentProvider('commit', 'tree_moved_links', $link_placeholders)); break; default: } } return $tree; } } ?>