Add commitdiff support
Add commitdiff support

--- a/config.inc.php
+++ b/config.inc.php
@@ -44,8 +44,9 @@
 /*
  * gittmp
  * Location for temporary files for diffs
+ * (don't forget trailing slash!)
  */
-$gitphp_conf['gittmp'] = "/tmp/gitweb";
+$gitphp_conf['gittmp'] = "/tmp/gitphp/";
 
 /*
  * title

--- a/gitphp.lib.php
+++ b/gitphp.lib.php
@@ -20,6 +20,20 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
+
+function prep_tmpdir($dir)
+{
+	if (file_exists($dir)) {
+		if (is_dir($dir)) {
+			if (!is_writeable($dir))
+				return "Specified tmpdir is not writeable!";
+		} else
+			return "Specified tmpdir is not a directory";
+	} else
+		if (!mkdir($dir,0700))
+			return "Could not create tmpdir";
+	return TRUE;
+}
 
 function git_read_projects($projectroot,$projectlist)
 {
@@ -791,5 +805,115 @@
 	$tpl->display("commit_footer.tpl");
 }
 
+function git_diff_print($proj,$from,$from_name,$to,$to_name,$format = "html")
+{
+	global $gitphp_conf,$tpl;
+	$from_tmp = "/dev/null";
+	$to_tmp = "/dev/null";
+	$pid = posix_getpid();
+	if (isset($from)) {
+		$from_tmp = $gitphp_conf['gittmp'] . "gitphp_" . $pid . "_from";
+		shell_exec("env GIT_DIR=" . $proj . " " . $gitphp_conf['gitbin'] . "git-cat-file blob " . $from . " > " . $from_tmp);
+	}
+	if (isset($to)) {
+		$to_tmp = $gitphp_conf['gittmp'] . "gitphp_" . $pid . "_to";
+		shell_exec("env GIT_DIR=" . $proj . " " . $gitphp_conf['gitbin'] . "git-cat-file blob " . $to . " > " . $to_tmp);
+	}
+	$diffout = shell_exec("diff -u -p -L '" . $from_name . "' -L '" . $to_name . "' " . $from_tmp . " " . $to_tmp);
+	if ($format == "plain")
+		echo $diffout;
+	else {
+		$line = strtok($diffout,"\n");
+		while ($line !== false) {
+			$start = substr($line,0,1);
+			unset($color);
+			if ($start == "+")
+				$color = "#008800";
+			else if ($start == "-")
+				$color = "#cc0000";
+			else if ($start == "@")
+				$color = "#990099";
+			if ($start != "\\") {
+			/*
+				while (($pos = strpos($line,"\t")) !== false) {
+					if ($c = (8 - (($pos - 1) % 8))) {
+						$spaces = "";
+						for ($i = 0; $i < $c; $i++)
+							$spaces .= " ";
+						preg_replace('/\t/',$spaces,$line,1);
+					}
+				}
+			 */
+				$tpl->clear_all_assign();
+				$tpl->assign("line",htmlentities($line));
+				if (isset($color))
+					$tpl->assign("color",$color);
+				$tpl->display("diff_line.tpl");
+			}
+			$line = strtok("\n");
+		}
+	}
+	if (isset($from))
+		unlink($from_tmp);
+	if (isset($to))
+		unlink($to_tmp);
+}
+
+function git_commitdiff($projectroot,$project,$hash,$hash_parent)
+{
+	global $gitphp_conf,$tpl;
+	$ret = prep_tmpdir($gitphp_conf['gittmp']);
+	if ($ret !== TRUE) {
+		echo $ret;
+		return;
+	}
+	$co = git_read_commit($projectroot . $project, $hash);
+	if (!isset($hash_parent))
+		$hash_parent = $co['parent'];
+	$difftree = array();
+	$diffout = shell_exec("env GIT_DIR=" . $projectroot . $project . " " . $gitphp_conf['gitbin'] . "git-diff-tree -r " . $hash_parent . " " . $hash);
+	$tok = strtok($diffout,"\n");
+	while ($tok !== false) {
+		$difftree[] = $tok;
+		$tok = strtok("\n");
+	}
+	$refs = read_info_ref($projectroot . $project);
+	$tpl->clear_all_assign();
+	$tpl->assign("project",$project);
+	$tpl->assign("hash",$hash);
+	$tpl->assign("tree",$co['tree']);
+	$tpl->assign("hashparent",$hash_parent);
+	$tpl->display("commitdiff_nav.tpl");
+	$tpl->assign("title",$co['title']);
+	if (isset($refs[$co['id']]))
+		$tpl->assign("commitref",$refs[$co['id']]);
+	$tpl->assign("comment",$co['comment']);
+	$tpl->display("commitdiff_header.tpl");
+
+	foreach ($difftree as $i => $line) {
+		if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs)) {
+			$tpl->clear_all_assign();
+			$tpl->assign("from_mode",$regs[1]);
+			$tpl->assign("to_mode",$regs[2]);
+			$tpl->assign("from_id",$regs[3]);
+			$tpl->assign("to_id",$regs[4]);
+			$tpl->assign("status",$regs[5]);
+			$tpl->assign("file",$regs[6]);
+			$tpl->assign("from_type",file_type($regs[1]));
+			$tpl->assign("to_type",file_type($regs[2]));
+			$tpl->display("commitdiff_item.tpl");
+			if ($regs[5] == "A")
+				git_diff_print($projectroot . $project, null,"/dev/null",$regs[4],"b/" . $regs[6]);
+			else if ($regs[5] == "D")
+				git_diff_print($projectroot . $project, $regs[3],"a/" . $regs[6],null,"/dev/null");
+			else if (($regs[5] == "M") && ($regs[3] != $regs[4]))
+				git_diff_print($projectroot . $project, $regs[3],"a/" . $regs[6],$regs[4],"b/" . $regs[6]);
+		}
+	}
+
+	$tpl->clear_all_assign();
+	$tpl->display("commitdiff_footer.tpl");
+}
+
 ?>
 

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -70,6 +70,9 @@
 				case "commit":
 					git_commit($gitphp_conf['projectroot'],$_GET['p'],$_GET['h']);
 					break;
+				case "commitdiff":
+					git_commitdiff($gitphp_conf['projectroot'],$_GET['p'],$_GET['h'],$_GET['hp']);
+					break;
 				default:
 					echo "Unknown action";
 					break;

--- /dev/null
+++ b/templates/commitdiff_footer.tpl
@@ -1,1 +1,24 @@
+{*
+ *  commitdiff_footer.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Commitdiff view footer template
+ *
+ *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
+ *
+ *  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 2 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *}
+ <br />
+ </div>
 

--- /dev/null
+++ b/templates/commitdiff_header.tpl
@@ -1,1 +1,28 @@
+{*
+ *  commitdiff_header.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Commitdiff view header template
+ *
+ *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
+ *
+ *  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 2 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *}
+ <div><a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}" class="title">{$title}{if $commitref} <span class="tag">{$commitref}</span>{/if}</a></div>
+ <div class="page_body">
+ {foreach from=$comment item=line}
+ {$line}<br />
+ {/foreach}
+ <br />
 

--- /dev/null
+++ b/templates/commitdiff_item.tpl
@@ -1,1 +1,37 @@
+{*
+ *  commitdiff_item.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Commitdiff view item template
+ *
+ *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
+ *
+ *  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 2 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *}
+ {if $status == "A"}
+   <div class="diff_info">
+   {$to_type}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$to_id}&hb={$hash}&f={$file}">{$to_id}</a>(new)
+   </div>
+ {elseif $status == "D"}
+   <div class="diff_info">
+   {$from_type}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$from_id}&hb={$hash}&f={$file}">{$from_id}</a>(deleted)
+   </div>
+ {elseif $status == "M"}
+   {if $from_id != $to_id}
+     <div class="diff_info">
+     {$from_type}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$from_id}&hb={$hash}&f={$file}">{$from_id}</a> -> {$to_type}:<a href="{$SCRIPT_NAME}?p={$project}&a=blob&h={$to_id}&hb={$hash}&f={$file}">{$to_id}</a>
+     </div>
+   {/if}
+ {/if}
 

--- /dev/null
+++ b/templates/commitdiff_nav.tpl
@@ -1,1 +1,27 @@
+{*
+ *  commitdiff_nav.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Commitdiff view nav template
+ *
+ *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
+ *
+ *  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 2 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *}
+ <div class="page_nav">
+ <a href="{$SCRIPT_NAME}?p={$project}&a=summary">summary</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h={$hash}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h={$hash}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=commit&h={$hash}">commit</a> | commitdiff | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h={$tree}&hb={$hash}">tree</a><br /><a href="{$SCRIPT_NAME}?p={$project}&a=commitdiff_plain&h={$hash}&hp={$hashparent}">plain</a>
+ </div>
+ <br /><br />
+ </div>
 

--- /dev/null
+++ b/templates/diff_line.tpl
@@ -1,1 +1,23 @@
+{*
+ *  diff_line.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Diff line template
+ *
+ *  Copyright (C) 2006 Christopher Han <xiphux@gmail.com>
+ *
+ *  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 2 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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *}
+ <div class="pre"{if $color} style="color:{$color};"{/if}>{$line}</div>
 

comments