started with commitdiff page
authorpk910 <philipp@zoelle1.de>
Fri, 15 Feb 2013 08:54:21 +0000 (09:54 +0100)
committerpk910 <philipp@zoelle1.de>
Fri, 15 Feb 2013 08:54:21 +0000 (09:54 +0100)
htdocs/lib/GitCommand.class.php
htdocs/pages/commit.class.php
htdocs/pages/commitdiff.class.php [new file with mode: 0644]
htdocs/templates/default/commit.tpl
htdocs/templates/default/commitdiff.tpl [new file with mode: 0644]
htdocs/templates/default/main.tpl

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);
+       }
 }
index 3c10b4486d1798bb7675eaac08b9de1863202158..389efaabf38acbbc7837f70a8975840bee8a37c8 100644 (file)
  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
  */
 
-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 (file)
index 0000000..0897f5c
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+/* commitdiff.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/>. 
+ */
+
+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', '<span class="atnight">'.gmdate('H:i', $author_local_time).'</span>');
+               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', '<span class="atnight">'.gmdate('H:i', $committer_local_time).'</span>');
+               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
index c77e90599750294b50eff7ced4a3b1b9d3439be2..6164ed1fa8c17b0e342bfc31dfb7732d70761ae4 100644 (file)
@@ -46,9 +46,6 @@
 <div class="page_body">
 %full_message%<br/>
 </div>
-
-<div class="list_head">
-</div>
 %difftree%
 
 
@@ -58,7 +55,7 @@
                <td class="sha1"><a class="list" href="?p=%project%&a=commit&h=%hash%">%hash%</a></td>
                <td class="link">
                        <a href="?p=%project%&a=commit&h=%hash%">commit</a> | 
-                       <a href="?p=%project%&a=commitdiff&h=%head%;hp=%hash%">diff</a>
+                       <a href="?p=%project%&a=commitdiff&h=%head%&hp=%hash%">diff</a>
                </td>
        </tr>
 
 <span class="tag" title="tags/%name%">%name%</span>
 
 # [difftree]
+<div class="list_head">
+%tree_count%
+</div>
 <table class="diff_tree%class%">
 %tree%
 </table>
 
+# [tree_count]
+%count% files changed:
+
 # [tree]
 <tr class="%class%">
        <td>%file%</td>
diff --git a/htdocs/templates/default/commitdiff.tpl b/htdocs/templates/default/commitdiff.tpl
new file mode 100644 (file)
index 0000000..0ee2b38
--- /dev/null
@@ -0,0 +1,39 @@
+# [main]
+<div class="header">
+<a class="title" href="?p=%project%&a=commitdiff&h=%hash%">%message% %refs%</a>
+</div>
+<div class="title_text">
+<table class="object_header">
+       <tr>
+               <td>author</td>
+               <td>
+                       <a title="Search for commits authored by %author%" class="list" href="?p=%project%&a=search&h=%hash%&s=%author%&st=author">%author%</a> 
+                       <a title="Search for commits authored by %author_mail%" class="list" href="?p=%project%&a=search&h=%hash%&s=%author_mail%&st=author">&lt;%author_mail%&gt;</a>
+               </td>
+               <td rowspan="2"></td>
+       </tr>
+       <tr>
+               <td></td>
+               <td> %author_date% (%author_local_date% %author_timezone%)</td>
+       </tr>
+       <tr>
+               <td>committer</td>
+               <td>
+                       <a title="Search for commits committed by %committer%" class="list" href="?p=%project%&a=search&h=%hash%&s=pk910&st=committer">%committer%</a> 
+                       <a title="Search for commits committed by %committer_mail%" class="list" href="?p=%project%&a=search&h=%hash%&s=%committer_mail%&st=committer">&lt;%committer_mail%&gt;</a>
+               </td>
+               <td rowspan="2"></td>
+       </tr>
+       <tr>
+               <td></td>
+               <td> %committer_date% (%committer_local_date% %committer_timezone%)</td>
+       </tr>
+</table>
+</div>
+<div class="page_body">
+%difftree%
+<br/>
+<div class="patchset">
+%patchset%
+</div>
+</div>
\ No newline at end of file
index d3908a59e682709bc8ddfae82d4c3f5868e00455..38f7b5888bdc2f7db4de4b98256bb123cf9e1d9c 100644 (file)
@@ -79,7 +79,7 @@ Rendertime: %rendertime% sec
 </div>
 
 # [project_header_nav_link]
-<a href="/?p=%project%&a=%link%">%name%</a>
+<a href="/?p=%project%&a=%link%&h=%project_head%">%name%</a>
 
 # [project_header_nav_active]
 %name%