From: pk910 Date: Fri, 15 Feb 2013 08:54:21 +0000 (+0100) Subject: started with commitdiff page X-Git-Url: http://git.pk910.de/?p=phpgitweb.git;a=commitdiff_plain;h=38cb4c7eb8706a5e500957185493e2025fde5dc1 started with commitdiff page --- diff --git a/htdocs/lib/GitCommand.class.php b/htdocs/lib/GitCommand.class.php index c06e0fb..a8ede91 100644 --- a/htdocs/lib/GitCommand.class.php +++ b/htdocs/lib/GitCommand.class.php @@ -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); + } } diff --git a/htdocs/pages/commit.class.php b/htdocs/pages/commit.class.php index 3c10b44..389efaa 100644 --- a/htdocs/pages/commit.class.php +++ b/htdocs/pages/commit.class.php @@ -16,24 +16,33 @@ * along with this program. If not, see . */ -require_once('pages/shortlog.class.php'); - 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'); - $tree = GitCommand::get_commit_changes($project['path'], $commit['id'], $commit['parent']); + 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(count($tree) == 0) + 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; } @@ -138,7 +147,7 @@ class difftree { } } else $tree->set('specials', ''); - if($entry['from_id'] != $entry['to_id']) + 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; @@ -215,7 +224,7 @@ class page_commit { else $this->page->set('committer_local_date', gmdate('H:i', $committer_local_time)); $this->page->set('committer_timezone', $commit['committer_timezone']); - $this->page->set('message', htmlentities(Tools::chop_text($commit['text'], 50, 5))); + $this->page->set('message', htmlentities(Tools::chop_text($commit['text'], 80, 5))); $this->page->set('full_message', htmlentities($commit['text'])); $this->page->set('tree_hash', $commit['tree']); foreach($commit['parent'] as $parent) { diff --git a/htdocs/pages/commitdiff.class.php b/htdocs/pages/commitdiff.class.php new file mode 100644 index 0000000..0897f5c --- /dev/null +++ b/htdocs/pages/commitdiff.class.php @@ -0,0 +1,99 @@ +. + */ + +require_once("pages/commit.class.php"); + +class page_commitdiff { + private $page, $phpgitweb; + private $commitid; + + public function main($phpgitweb, $project) { + $this->phpgitweb = $phpgitweb; + if(!$project) + return new ContentProvider('main', 'err400'); + $project['refs'] = $phpgitweb->get_project_loader()->getProjectRefs($project); + $phpgitweb->append_header_nav("commit", null, true); + $phpgitweb->append_title("commit"); + + $commit_loader = new CommitLoader($project); + + if(array_key_exists('h', $_GET)) + $commitid = $_GET['h']; + else + $commitid = "HEAD"; + + $commit = $commit_loader->load($commitid); + if(!$commit) + return new ContentProvider('main', 'err404_object'); + + ContentProvider::overall_set('project_head', $commit['id']); + + + $this->page = new ContentProvider('commitdiff', 'main'); + $this->page->set('hash', $commit['id']); + $this->page->set('author', htmlentities($commit['author'])); + $this->page->set('author_mail', htmlentities($commit['author_mail'])); + $this->page->set('author_date', gmdate('r', $commit['author_time'])); + $author_local_time = $commit['author_time'] + Tools::parseTimeZone($commit['author_timezone']); + if(gmdate('H', $author_local_time) < 6) + $this->page->set('author_local_date', ''.gmdate('H:i', $author_local_time).''); + else + $this->page->set('author_local_date', gmdate('H:i', $author_local_time)); + $this->page->set('author_timezone', $commit['author_timezone']); + $this->page->set('committer', htmlentities($commit['committer'])); + $this->page->set('committer_mail', htmlentities($commit['committer_mail'])); + $this->page->set('committer_date', gmdate('r', $commit['committer_time'])); + $committer_local_time = $commit['committer_time'] + Tools::parseTimeZone($commit['committer_timezone']); + if(gmdate('H', $committer_local_time) < 6) + $this->page->set('committer_local_date', ''.gmdate('H:i', $committer_local_time).''); + else + $this->page->set('committer_local_date', gmdate('H:i', $committer_local_time)); + $this->page->set('committer_timezone', $commit['committer_timezone']); + $this->page->set('message', htmlentities(Tools::chop_text($commit['text'], 80, 5))); + + + $refs = new ContentProvider('commit', 'commit_refs'); + $found = false; + foreach($project['refs'] as $ref => $rhash) { + if(strtolower($rhash) == strtolower($commit['id'])) { + $refexp = explode('/', $ref, 3); + $reftype = $refexp[1]; + if($reftype == 'heads') + $reftype = 'head'; + else if($reftype == 'remotes') + $reftype = 'remote'; + else if($reftype == 'tags') + $reftype = 'tag'; + $refs->append('refs', new ContentProvider('commit', 'commit_ref_'.$reftype, array("name" => $refexp[2], "ref_link" => $ref))); + $found = true; + } + } + $this->page->set('refs', ($found ? $refs : "")); + + $difftree = new difftree(); + $diff_data = GitCommand::get_commit_diff($project['path'], $commit['id'], $commit['parent']); + $difftree->push_difftree_data($diff_data['tree']); + $this->page->set('difftree', $difftree->generate_difftree($project, $commit, true)); + + + + return $this->page; + } +} + +?> \ No newline at end of file diff --git a/htdocs/templates/default/commit.tpl b/htdocs/templates/default/commit.tpl index c77e905..6164ed1 100644 --- a/htdocs/templates/default/commit.tpl +++ b/htdocs/templates/default/commit.tpl @@ -46,9 +46,6 @@
%full_message%
- -
-
%difftree% @@ -58,7 +55,7 @@ %hash% commit | - diff + diff @@ -75,10 +72,16 @@ %name% # [difftree] +
+%tree_count% +
%tree%
+# [tree_count] +%count% files changed: + # [tree] %file% diff --git a/htdocs/templates/default/commitdiff.tpl b/htdocs/templates/default/commitdiff.tpl new file mode 100644 index 0000000..0ee2b38 --- /dev/null +++ b/htdocs/templates/default/commitdiff.tpl @@ -0,0 +1,39 @@ +# [main] + +
+ + + + + + + + + + + + + + + + + + + +
author + %author% + <%author_mail%> +
%author_date% (%author_local_date% %author_timezone%)
committer + %committer% + <%committer_mail%> +
%committer_date% (%committer_local_date% %committer_timezone%)
+
+
+%difftree% +
+
+%patchset% +
+
\ No newline at end of file diff --git a/htdocs/templates/default/main.tpl b/htdocs/templates/default/main.tpl index d3908a5..38f7b58 100644 --- a/htdocs/templates/default/main.tpl +++ b/htdocs/templates/default/main.tpl @@ -79,7 +79,7 @@ Rendertime: %rendertime% sec # [project_header_nav_link] -%name% +%name% # [project_header_nav_active] %name%