Enable caching
Enable caching

file:b/cache/.gitignore (new)
--- /dev/null
+++ b/cache/.gitignore
@@ -1,1 +1,2 @@
+*
 

--- a/include/display.git_blob.php
+++ b/include/display.git_blob.php
@@ -18,72 +18,77 @@
 function git_blob($projectroot, $project, $hash, $file, $hashbase)
 {
 	global $gitphp_conf,$tpl;
-	$head = git_read_head($projectroot . $project);
-	if (!isset($hashbase))
-		$hashbase = $head;
-	if (!isset($hash) && isset($file))
-		$hash = git_get_hash_by_path($projectroot . $project, $hashbase,$file,"blob");
-	$catout = git_cat_file($projectroot . $project, $hash);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("hashbase",$hashbase);
-	$tpl->assign("head", $head);
-	if ($co = git_read_commit($projectroot . $project, $hashbase)) {
-		$tpl->assign("fullnav",TRUE);
-		$refs = read_info_ref($projectroot . $project);
-		$tpl->assign("tree",$co['tree']);
-		$tpl->assign("title",$co['title']);
-		if (isset($file))
-			$tpl->assign("file",$file);
-		if ($hashbase == "HEAD") {
-			if (isset($refs[$head]))
-				$tpl->assign("hashbaseref",$refs[$head]);
+
+	$cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . sha1($file);
+
+	if (!$tpl->is_cached('blob.tpl',$cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		if (!isset($hashbase))
+			$hashbase = $head;
+		if (!isset($hash) && isset($file))
+			$hash = git_get_hash_by_path($projectroot . $project, $hashbase,$file,"blob");
+		$catout = git_cat_file($projectroot . $project, $hash);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("hashbase",$hashbase);
+		$tpl->assign("head", $head);
+		if ($co = git_read_commit($projectroot . $project, $hashbase)) {
+			$tpl->assign("fullnav",TRUE);
+			$refs = read_info_ref($projectroot . $project);
+			$tpl->assign("tree",$co['tree']);
+			$tpl->assign("title",$co['title']);
+			if (isset($file))
+				$tpl->assign("file",$file);
+			if ($hashbase == "HEAD") {
+				if (isset($refs[$head]))
+					$tpl->assign("hashbaseref",$refs[$head]);
+			} else {
+				if (isset($refs[$hashbase]))
+					$tpl->assign("hashbaseref",$refs[$hashbase]);
+			}
+		}
+		$paths = git_path_trees($projectroot . $project, $hashbase, $file);
+		$tpl->assign("paths",$paths);
+
+		if ($gitphp_conf['filemimetype']) {
+			$mime = file_mime($catout,$file);
+			if ($mime)
+				$mimetype = strtok($mime, "/");
+		}
+
+		if ($mimetype == "image") {
+			$tpl->assign("mime", $mime);
+			$tpl->assign("data", base64_encode($catout));
 		} else {
-			if (isset($refs[$hashbase]))
-				$tpl->assign("hashbaseref",$refs[$hashbase]);
-		}
-	}
-	$paths = git_path_trees($projectroot . $project, $hashbase, $file);
-	$tpl->assign("paths",$paths);
-
-	if ($gitphp_conf['filemimetype']) {
-		$mime = file_mime($catout,$file);
-		if ($mime)
-			$mimetype = strtok($mime, "/");
-	}
-
-	if ($mimetype == "image") {
-		$tpl->assign("mime", $mime);
-		$tpl->assign("data", base64_encode($catout));
-	} else {
-		$usedgeshi = $gitphp_conf['geshi'];
-		if ($usedgeshi) {
-			$usedgeshi = FALSE;
-			include_once($gitphp_conf['geshiroot'] . "geshi.php");
-			if (class_exists("GeSHi")) {
-				$geshi = new GeSHi("",'php');
-				if ($geshi) {
-					$lang = "";
-					if (isset($file))
-						$lang = $geshi->get_language_name_from_extension(substr(strrchr($file,'.'),1));
-					if (isset($lang) && (strlen($lang) > 0)) {
-						$geshi->set_source($catout);
-						$geshi->set_language($lang);
-						$geshi->set_header_type(GESHI_HEADER_DIV);
-						$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS);
-						$tpl->assign("geshiout",$geshi->parse_code());
-						$usedgeshi = TRUE;
+			$usedgeshi = $gitphp_conf['geshi'];
+			if ($usedgeshi) {
+				$usedgeshi = FALSE;
+				include_once($gitphp_conf['geshiroot'] . "geshi.php");
+				if (class_exists("GeSHi")) {
+					$geshi = new GeSHi("",'php');
+					if ($geshi) {
+						$lang = "";
+						if (isset($file))
+							$lang = $geshi->get_language_name_from_extension(substr(strrchr($file,'.'),1));
+						if (isset($lang) && (strlen($lang) > 0)) {
+							$geshi->set_source($catout);
+							$geshi->set_language($lang);
+							$geshi->set_header_type(GESHI_HEADER_DIV);
+							$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS);
+							$tpl->assign("geshiout",$geshi->parse_code());
+							$usedgeshi = TRUE;
+						}
 					}
 				}
 			}
-		}
 
-		if (!$usedgeshi) {
-			$lines = explode("\n",$catout);
-			$tpl->assign("lines",$lines);
+			if (!$usedgeshi) {
+				$lines = explode("\n",$catout);
+				$tpl->assign("lines",$lines);
+			}
 		}
 	}
 
-	$tpl->display("blob.tpl");
+	$tpl->display('blob.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_blobdiff.php
+++ b/include/display.git_blobdiff.php
@@ -16,29 +16,34 @@
 function git_blobdiff($projectroot,$project,$hash,$hashbase,$hashparent,$file)
 {
 	global $tpl;
-	$ret = prep_tmpdir();
-	if ($ret !== TRUE) {
-		echo $ret;
-		return;
+
+	$cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . $hashparent . "|" . sha1($file);
+
+	if (!$tpl->is_cached('blobdiff.tpl', $cachekey)) {
+		$ret = prep_tmpdir();
+		if ($ret !== TRUE) {
+			echo $ret;
+			return;
+		}
+		$tpl->assign("hash",$hash);
+		$tpl->assign("hashparent",$hashparent);
+		$tpl->assign("hashbase",$hashbase);
+		if (isset($file))
+			$tpl->assign("file",$file);
+		if ($co = git_read_commit($projectroot . $project, $hashbase)) {
+			$tpl->assign("fullnav",TRUE);
+			$tpl->assign("tree",$co['tree']);
+			$tpl->assign("title",$co['title']);
+			$refs = read_info_ref($projectroot . $project);
+			if (isset($refs[$hashbase]))
+				$tpl->assign("hashbaseref",$refs[$hashbase]);
+		}
+		$paths = git_path_trees($projectroot . $project, $hashbase, $file);
+		$tpl->assign("paths",$paths);
+		$diffout = explode("\n",git_diff($projectroot . $project, $hashparent,($file?$file:$hashparent),$hash,($file?$file:$hash)));
+		$tpl->assign("diff",$diffout);
 	}
-	$tpl->assign("hash",$hash);
-	$tpl->assign("hashparent",$hashparent);
-	$tpl->assign("hashbase",$hashbase);
-	if (isset($file))
-		$tpl->assign("file",$file);
-	if ($co = git_read_commit($projectroot . $project, $hashbase)) {
-		$tpl->assign("fullnav",TRUE);
-		$tpl->assign("tree",$co['tree']);
-		$tpl->assign("title",$co['title']);
-		$refs = read_info_ref($projectroot . $project);
-		if (isset($refs[$hashbase]))
-			$tpl->assign("hashbaseref",$refs[$hashbase]);
-	}
-	$paths = git_path_trees($projectroot . $project, $hashbase, $file);
-	$tpl->assign("paths",$paths);
-	$diffout = explode("\n",git_diff($projectroot . $project, $hashparent,($file?$file:$hashparent),$hash,($file?$file:$hash)));
-	$tpl->assign("diff",$diffout);
-	$tpl->display("blobdiff.tpl");
+	$tpl->display('blobdiff.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_commit.php
+++ b/include/display.git_commit.php
@@ -16,78 +16,83 @@
 function git_commit($projectroot,$project,$hash)
 {
 	global $tpl;
-	$co = git_read_commit($projectroot . $project, $hash);
-	$ad = date_str($co['author_epoch'],$co['author_tz']);
-	$cd = date_str($co['committer_epoch'],$co['committer_tz']);
-	if (isset($co['parent'])) {
-		$root = "";
-		$parent = $co['parent'];
-	} else {
-		$root = "--root";
-		$parent = "";
+
+	$cachekey = sha1($project) . "|" . $hash;
+
+	if (!$tpl->is_cached('commit.tpl', $cachekey)) {
+		$co = git_read_commit($projectroot . $project, $hash);
+		$ad = date_str($co['author_epoch'],$co['author_tz']);
+		$cd = date_str($co['committer_epoch'],$co['committer_tz']);
+		if (isset($co['parent'])) {
+			$root = "";
+			$parent = $co['parent'];
+		} else {
+			$root = "--root";
+			$parent = "";
+		}
+		$diffout = git_diff_tree($projectroot . $project, $root . " " . $parent . " " . $hash, TRUE);
+		$difftree = explode("\n",$diffout);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("tree",$co['tree']);
+		if (isset($co['parent']))
+			$tpl->assign("parent",$co['parent']);
+		$tpl->assign("title",$co['title']);
+		$refs = read_info_ref($projectroot . $project);
+		if (isset($refs[$co['id']]))
+			$tpl->assign("commitref",$refs[$co['id']]);
+		$tpl->assign("author",$co['author']);
+		$tpl->assign("adrfc2822",$ad['rfc2822']);
+		$tpl->assign("adhourlocal",$ad['hour_local']);
+		$tpl->assign("adminutelocal",$ad['minute_local']);
+		$tpl->assign("adtzlocal",$ad['tz_local']);
+		$tpl->assign("committer",$co['committer']);
+		$tpl->assign("cdrfc2822",$cd['rfc2822']);
+		$tpl->assign("cdhourlocal",$cd['hour_local']);
+		$tpl->assign("cdminutelocal",$cd['minute_local']);
+		$tpl->assign("cdtzlocal",$cd['tz_local']);
+		$tpl->assign("id",$co['id']);
+		$tpl->assign("parents",$co['parents']);
+		$tpl->assign("comment",$co['comment']);
+		$tpl->assign("difftreesize",count($difftree)+1);
+		$difftreelines = array();
+		foreach ($difftree as $i => $line) {
+			if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$",$line,$regs)) {
+				$difftreeline = array();
+				$difftreeline["from_mode"] = $regs[1];
+				$difftreeline["to_mode"] = $regs[2];
+				$difftreeline["from_mode_cut"] = substr($regs[1],-4);
+				$difftreeline["to_mode_cut"] = substr($regs[2],-4);
+				$difftreeline["from_id"] = $regs[3];
+				$difftreeline["to_id"] = $regs[4];
+				$difftreeline["status"] = $regs[5];
+				$difftreeline["similarity"] = ltrim($regs[6],"0");
+				$difftreeline["file"] = $regs[7];
+				$difftreeline["from_file"] = strtok($regs[7],"\t");
+				$difftreeline["from_filetype"] = file_type($regs[1]);
+				$difftreeline["to_file"] = strtok("\t");
+				$difftreeline["to_filetype"] = file_type($regs[2]);
+				if ((octdec($regs[2]) & 0x8000) == 0x8000)
+					$difftreeline["isreg"] = TRUE;
+				$modestr = "";
+				if ((octdec($regs[1]) & 0x17000) != (octdec($regs[2]) & 0x17000))
+					$modestr .= " from " . file_type($regs[1]) . " to " . file_type($regs[2]);
+				if ((octdec($regs[1]) & 0777) != (octdec($regs[2]) & 0777)) {
+					if ((octdec($regs[1]) & 0x8000) && (octdec($regs[2]) & 0x8000))
+						$modestr .= " mode: " . (octdec($regs[1]) & 0777) . "->" . (octdec($regs[2]) & 0777);
+					else if (octdec($regs[2]) & 0x8000)
+						$modestr .= " mode: " . (octdec($regs[2]) & 0777);
+				}
+				$difftreeline["modechange"] = $modestr;
+				$simmodechg = "";
+				if ($regs[1] != $regs[2])
+					$simmodechg .= ", mode: " . (octdec($regs[2]) & 0777);
+				$difftreeline["simmodechg"] = $simmodechg;
+				$difftreelines[] = $difftreeline;
+			}
+		}
+		$tpl->assign("difftreelines",$difftreelines);
 	}
-	$diffout = git_diff_tree($projectroot . $project, $root . " " . $parent . " " . $hash, TRUE);
-	$difftree = explode("\n",$diffout);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("tree",$co['tree']);
-	if (isset($co['parent']))
-		$tpl->assign("parent",$co['parent']);
-	$tpl->assign("title",$co['title']);
-	$refs = read_info_ref($projectroot . $project);
-	if (isset($refs[$co['id']]))
-		$tpl->assign("commitref",$refs[$co['id']]);
-	$tpl->assign("author",$co['author']);
-	$tpl->assign("adrfc2822",$ad['rfc2822']);
-	$tpl->assign("adhourlocal",$ad['hour_local']);
-	$tpl->assign("adminutelocal",$ad['minute_local']);
-	$tpl->assign("adtzlocal",$ad['tz_local']);
-	$tpl->assign("committer",$co['committer']);
-	$tpl->assign("cdrfc2822",$cd['rfc2822']);
-	$tpl->assign("cdhourlocal",$cd['hour_local']);
-	$tpl->assign("cdminutelocal",$cd['minute_local']);
-	$tpl->assign("cdtzlocal",$cd['tz_local']);
-	$tpl->assign("id",$co['id']);
-	$tpl->assign("parents",$co['parents']);
-	$tpl->assign("comment",$co['comment']);
-	$tpl->assign("difftreesize",count($difftree)+1);
-	$difftreelines = array();
-	foreach ($difftree as $i => $line) {
-		if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$",$line,$regs)) {
-			$difftreeline = array();
-			$difftreeline["from_mode"] = $regs[1];
-			$difftreeline["to_mode"] = $regs[2];
-			$difftreeline["from_mode_cut"] = substr($regs[1],-4);
-			$difftreeline["to_mode_cut"] = substr($regs[2],-4);
-			$difftreeline["from_id"] = $regs[3];
-			$difftreeline["to_id"] = $regs[4];
-			$difftreeline["status"] = $regs[5];
-			$difftreeline["similarity"] = ltrim($regs[6],"0");
-			$difftreeline["file"] = $regs[7];
-			$difftreeline["from_file"] = strtok($regs[7],"\t");
-			$difftreeline["from_filetype"] = file_type($regs[1]);
-			$difftreeline["to_file"] = strtok("\t");
-			$difftreeline["to_filetype"] = file_type($regs[2]);
-			if ((octdec($regs[2]) & 0x8000) == 0x8000)
-				$difftreeline["isreg"] = TRUE;
-			$modestr = "";
-			if ((octdec($regs[1]) & 0x17000) != (octdec($regs[2]) & 0x17000))
-				$modestr .= " from " . file_type($regs[1]) . " to " . file_type($regs[2]);
-			if ((octdec($regs[1]) & 0777) != (octdec($regs[2]) & 0777)) {
-				if ((octdec($regs[1]) & 0x8000) && (octdec($regs[2]) & 0x8000))
-					$modestr .= " mode: " . (octdec($regs[1]) & 0777) . "->" . (octdec($regs[2]) & 0777);
-				else if (octdec($regs[2]) & 0x8000)
-					$modestr .= " mode: " . (octdec($regs[2]) & 0777);
-			}
-			$difftreeline["modechange"] = $modestr;
-			$simmodechg = "";
-			if ($regs[1] != $regs[2])
-				$simmodechg .= ", mode: " . (octdec($regs[2]) & 0777);
-			$difftreeline["simmodechg"] = $simmodechg;
-			$difftreelines[] = $difftreeline;
-		}
-	}
-	$tpl->assign("difftreelines",$difftreelines);
-	$tpl->display("commit.tpl");
+	$tpl->display('commit.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_commitdiff.php
+++ b/include/display.git_commitdiff.php
@@ -17,47 +17,52 @@
 function git_commitdiff($projectroot,$project,$hash,$hash_parent)
 {
 	global $tpl;
-	$ret = prep_tmpdir();
-	if ($ret !== TRUE) {
-		echo $ret;
-		return;
+
+	$cachekey = sha1($project) . "|" . $hash . "|" . $hash_parent;
+
+	if (!$tpl->is_cached('commitdiff.tpl', $cachekey)) {
+		$ret = prep_tmpdir();
+		if ($ret !== TRUE) {
+			echo $ret;
+			return;
+		}
+		$co = git_read_commit($projectroot . $project, $hash);
+		if (!isset($hash_parent))
+			$hash_parent = $co['parent'];
+		$diffout = git_diff_tree($projectroot . $project, $hash_parent . " " . $hash);
+		$difftree = explode("\n",$diffout);
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("tree",$co['tree']);
+		$tpl->assign("hashparent",$hash_parent);
+		$tpl->assign("title",$co['title']);
+		if (isset($refs[$co['id']]))
+			$tpl->assign("commitref",$refs[$co['id']]);
+		$tpl->assign("comment",$co['comment']);
+		$difftreelines = array();
+		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)) {
+				$difftreeline = array();
+				$difftreeline["from_mode"] = $regs[1];
+				$difftreeline["to_mode"] = $regs[2];
+				$difftreeline["from_id"] = $regs[3];
+				$difftreeline["to_id"] = $regs[4];
+				$difftreeline["status"] = $regs[5];
+				$difftreeline["file"] = $regs[6];
+				$difftreeline["from_type"] = file_type($regs[1]);
+				$difftreeline["to_type"] = file_type($regs[2]);
+				if ($regs[5] == "A")
+					$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, null,"/dev/null",$regs[4],"b/" . $regs[6]));
+				else if ($regs[5] == "D")
+					$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, $regs[3],"a/" . $regs[6],null,"/dev/null"));
+				else if (($regs[5] == "M") && ($regs[3] != $regs[4]))
+					$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, $regs[3],"a/" . $regs[6],$regs[4],"b/" . $regs[6]));
+				$difftreelines[] = $difftreeline;
+			}
+		}
+		$tpl->assign("difftreelines",$difftreelines);
 	}
-	$co = git_read_commit($projectroot . $project, $hash);
-	if (!isset($hash_parent))
-		$hash_parent = $co['parent'];
-	$diffout = git_diff_tree($projectroot . $project, $hash_parent . " " . $hash);
-	$difftree = explode("\n",$diffout);
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("tree",$co['tree']);
-	$tpl->assign("hashparent",$hash_parent);
-	$tpl->assign("title",$co['title']);
-	if (isset($refs[$co['id']]))
-		$tpl->assign("commitref",$refs[$co['id']]);
-	$tpl->assign("comment",$co['comment']);
-	$difftreelines = array();
-	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)) {
-			$difftreeline = array();
-			$difftreeline["from_mode"] = $regs[1];
-			$difftreeline["to_mode"] = $regs[2];
-			$difftreeline["from_id"] = $regs[3];
-			$difftreeline["to_id"] = $regs[4];
-			$difftreeline["status"] = $regs[5];
-			$difftreeline["file"] = $regs[6];
-			$difftreeline["from_type"] = file_type($regs[1]);
-			$difftreeline["to_type"] = file_type($regs[2]);
-			if ($regs[5] == "A")
-				$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, null,"/dev/null",$regs[4],"b/" . $regs[6]));
-			else if ($regs[5] == "D")
-				$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, $regs[3],"a/" . $regs[6],null,"/dev/null"));
-			else if (($regs[5] == "M") && ($regs[3] != $regs[4]))
-				$difftreeline['diffout'] = explode("\n",git_diff($projectroot . $project, $regs[3],"a/" . $regs[6],$regs[4],"b/" . $regs[6]));
-			$difftreelines[] = $difftreeline;
-		}
-	}
-	$tpl->assign("difftreelines",$difftreelines);
-	$tpl->display("commitdiff.tpl");
+	$tpl->display('commitdiff.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_commitdiff_plain.php
+++ b/include/display.git_commitdiff_plain.php
@@ -19,49 +19,55 @@
 function git_commitdiff_plain($projectroot,$project,$hash,$hash_parent)
 {
 	global $tpl;
-	$ret = prep_tmpdir();
-	if ($ret !== TRUE) {
-		echo $ret;
-		return;
-	}
-	$co = git_read_commit($projectroot . $project, $hash);
-	if (!isset($hash_parent))
-		$hash_parent = $co['parent'];
-	$diffout = git_diff_tree($projectroot . $project, $hash_parent . " " . $hash);
-	$difftree = explode("\n",$diffout);
-	$refs = read_info_ref($projectroot . $project,"tags");
-	$listout = git_rev_list($projectroot . $project, "HEAD");
-	$tok = strtok($listout,"\n");
-	while ($tok !== false) {
-		if (isset($refs[$tok]))
-			$tagname = $refs[$tok];
-		if ($tok == $hash)
-			break;
-		$tok = strtok("\n");
-	}
+
+	$cachekey = sha1($project) . "|" . $hash . "|" . $hash_parent;
+
 	header("Content-type: text/plain; charset=UTF-8");
 	header("Content-disposition: inline; filename=\"git-" . $hash . ".patch\"");
-	$ad = date_str($co['author_epoch'],$co['author_tz']);
-	$tpl->assign("from",$co['author']);
-	$tpl->assign("date",$ad['rfc2822']);
-	$tpl->assign("subject",$co['title']);
-	if (isset($tagname))
-		$tpl->assign("tagname",$tagname);
-	$tpl->assign("url",script_url() . "?p=" . $project . "&a=commitdiff&h=" . $hash);
-	$tpl->assign("comment",$co['comment']);
-	$diffs = array();
-	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)) {
-			if ($regs[5] == "A")
-				$diffs[] = git_diff($projectroot . $project, null, "/dev/null", $regs[4], "b/" . $regs[6]);
-			else if ($regs[5] == "D")
-				$diffs[] = git_diff($projectroot . $project, $regs[3], "a/" . $regs[6], null, "/dev/null");
-			else if ($regs[5] == "M")
-				$diffs[] = git_diff($projectroot . $project, $regs[3], "a/" . $regs[6], $regs[4], "b/" . $regs[6]);
+
+	if (!$tpl->is_cached('diff_plaintext.tpl', $cachekey)) {
+		$ret = prep_tmpdir();
+		if ($ret !== TRUE) {
+			echo $ret;
+			return;
 		}
+		$co = git_read_commit($projectroot . $project, $hash);
+		if (!isset($hash_parent))
+			$hash_parent = $co['parent'];
+		$diffout = git_diff_tree($projectroot . $project, $hash_parent . " " . $hash);
+		$difftree = explode("\n",$diffout);
+		$refs = read_info_ref($projectroot . $project,"tags");
+		$listout = git_rev_list($projectroot . $project, "HEAD");
+		$tok = strtok($listout,"\n");
+		while ($tok !== false) {
+			if (isset($refs[$tok]))
+				$tagname = $refs[$tok];
+			if ($tok == $hash)
+				break;
+			$tok = strtok("\n");
+		}
+		$ad = date_str($co['author_epoch'],$co['author_tz']);
+		$tpl->assign("from",$co['author']);
+		$tpl->assign("date",$ad['rfc2822']);
+		$tpl->assign("subject",$co['title']);
+		if (isset($tagname))
+			$tpl->assign("tagname",$tagname);
+		$tpl->assign("url",script_url() . "?p=" . $project . "&a=commitdiff&h=" . $hash);
+		$tpl->assign("comment",$co['comment']);
+		$diffs = array();
+		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)) {
+				if ($regs[5] == "A")
+					$diffs[] = git_diff($projectroot . $project, null, "/dev/null", $regs[4], "b/" . $regs[6]);
+				else if ($regs[5] == "D")
+					$diffs[] = git_diff($projectroot . $project, $regs[3], "a/" . $regs[6], null, "/dev/null");
+				else if ($regs[5] == "M")
+					$diffs[] = git_diff($projectroot . $project, $regs[3], "a/" . $regs[6], $regs[4], "b/" . $regs[6]);
+			}
+		}
+		$tpl->assign("diffs",$diffs);
 	}
-	$tpl->assign("diffs",$diffs);
-	$tpl->display("diff_plaintext.tpl");
+	$tpl->display('diff_plaintext.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_heads.php
+++ b/include/display.git_heads.php
@@ -13,11 +13,16 @@
 function git_heads($projectroot,$project)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	$tpl->assign("head",$head);
-	$headlist = git_read_refs($projectroot, $project, "refs/heads");
-	$tpl->assign("headlist",$headlist);
-	$tpl->display("heads.tpl");
+
+	$cachekey = sha1($project);
+
+	if (!$tpl->is_cached('heads.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		$tpl->assign("head",$head);
+		$headlist = git_read_refs($projectroot, $project, "refs/heads");
+		$tpl->assign("headlist",$headlist);
+	}
+	$tpl->display('heads.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_history.php
+++ b/include/display.git_history.php
@@ -17,46 +17,51 @@
 function git_history($projectroot,$project,$hash,$file)
 {
 	global $tpl;
-	if (!isset($hash))
-		$hash = git_read_head($projectroot . $project);
-	$co = git_read_commit($projectroot . $project, $hash);
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	if (isset($refs[$hash]))
-		$tpl->assign("hashbaseref",$refs[$hash]);
-	$tpl->assign("tree",$co['tree']);
-	$tpl->assign("title",$co['title']);
-	$paths = git_path_trees($projectroot . $project, $hash, $file);
-	$tpl->assign("paths",$paths);
-	$cmdout = git_history_list($projectroot . $project, $hash, $file);
-	$lines = explode("\n", $cmdout);
-	$historylines = array();
-	foreach ($lines as $i => $line) {
-		if (ereg("^([0-9a-fA-F]{40})",$line,$regs))
-			$commit = $regs[1];
-		else if (ereg(":([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs) && isset($commit)) {
-				$historyline = array();
-				$co = git_read_commit($projectroot . $project, $commit);
-				$historyline["agestringage"] = $co['age_string_age'];
-				$historyline["agestringdate"] = $co['age_string_date'];
-				$historyline["authorname"] = $co['author_name'];
-				$historyline["commit"] = $commit;
-				$historyline["file"] = $file;
-				$historyline["title"] = $co['title_short'];
-				if (isset($refs[$commit]))
-					$historyline["commitref"] = $refs[$commit];
-				$blob = git_get_hash_by_path($projectroot . $project, $hash,$file);
-				$blob_parent = git_get_hash_by_path($projectroot . $project, $commit,$file);
-				if ($blob && $blob_parent && ($blob != $blob_parent)) {
-					$historyline["blob"] = $blob;
-					$historyline["blobparent"] = $blob_parent;
-				}
-				$historylines[] = $historyline;
-				unset($commit);
+
+	$cachekey = sha1($project) . "|" . $hash . "|" . sha1($file);
+
+	if (!$tpl->is_cached('history.tpl', $cachekey)) {
+		if (!isset($hash))
+			$hash = git_read_head($projectroot . $project);
+		$co = git_read_commit($projectroot . $project, $hash);
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		if (isset($refs[$hash]))
+			$tpl->assign("hashbaseref",$refs[$hash]);
+		$tpl->assign("tree",$co['tree']);
+		$tpl->assign("title",$co['title']);
+		$paths = git_path_trees($projectroot . $project, $hash, $file);
+		$tpl->assign("paths",$paths);
+		$cmdout = git_history_list($projectroot . $project, $hash, $file);
+		$lines = explode("\n", $cmdout);
+		$historylines = array();
+		foreach ($lines as $i => $line) {
+			if (ereg("^([0-9a-fA-F]{40})",$line,$regs))
+				$commit = $regs[1];
+			else if (ereg(":([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$",$line,$regs) && isset($commit)) {
+					$historyline = array();
+					$co = git_read_commit($projectroot . $project, $commit);
+					$historyline["agestringage"] = $co['age_string_age'];
+					$historyline["agestringdate"] = $co['age_string_date'];
+					$historyline["authorname"] = $co['author_name'];
+					$historyline["commit"] = $commit;
+					$historyline["file"] = $file;
+					$historyline["title"] = $co['title_short'];
+					if (isset($refs[$commit]))
+						$historyline["commitref"] = $refs[$commit];
+					$blob = git_get_hash_by_path($projectroot . $project, $hash,$file);
+					$blob_parent = git_get_hash_by_path($projectroot . $project, $commit,$file);
+					if ($blob && $blob_parent && ($blob != $blob_parent)) {
+						$historyline["blob"] = $blob;
+						$historyline["blobparent"] = $blob_parent;
+					}
+					$historylines[] = $historyline;
+					unset($commit);
+			}
 		}
+		$tpl->assign("historylines",$historylines);
 	}
-	$tpl->assign("historylines",$historylines);
-	$tpl->display("history.tpl");
+	$tpl->display('history.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_log.php
+++ b/include/display.git_log.php
@@ -16,51 +16,56 @@
 function git_log($projectroot,$project,$hash,$page)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	if (!isset($hash))
-		$hash = $head;
-	if (!isset($page))
-		$page = 0;
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("head",$head);
 
-	if ($page)
-		$tpl->assign("page",$page);
+	$cachekey = sha1($project) . "|" . $hash . "|" . $page;
 
-	$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100));
+	if (!$tpl->is_cached('log.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		if (!isset($hash))
+			$hash = $head;
+		if (!isset($page))
+			$page = 0;
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("head",$head);
 
-	$revlistcount = count($revlist);
-	$tpl->assign("revlistcount",$revlistcount);
+		if ($page)
+			$tpl->assign("page",$page);
 
-	if (!$revlist) {
-		$tpl->assign("norevlist",TRUE);
-		$co = git_read_commit($hash);
-		$tpl->assign("lastchange",$co['age_string']);
+		$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100));
+
+		$revlistcount = count($revlist);
+		$tpl->assign("revlistcount",$revlistcount);
+
+		if (!$revlist) {
+			$tpl->assign("norevlist",TRUE);
+			$co = git_read_commit($hash);
+			$tpl->assign("lastchange",$co['age_string']);
+		}
+
+		$commitlines = array();
+		$commitcount = min(100,$revlistcount);
+		for ($i = 0; $i < $commitcount; $i++) {
+			$commit = $revlist[$i];
+			if (isset($commit) && strlen($commit) > 1) {
+				$commitline = array();
+				$co = git_read_commit($projectroot . $project, $commit);
+				$ad = date_str($co['author_epoch']);
+				$commitline["project"] = $project;
+				$commitline["commit"] = $commit;
+				if (isset($refs[$commit]))
+					$commitline["commitref"] = $refs[$commit];
+				$commitline["agestring"] = $co['age_string'];
+				$commitline["title"] = $co['title'];
+				$commitline["authorname"] = $co['author_name'];
+				$commitline["rfc2822"] = $ad['rfc2822'];
+				$commitline["comment"] = $co['comment'];
+				$commitlines[] = $commitline;
+			}
+		}
+		$tpl->assign("commitlines",$commitlines);
 	}
-
-	$commitlines = array();
-	$commitcount = min(100,$revlistcount);
-	for ($i = 0; $i < $commitcount; $i++) {
-		$commit = $revlist[$i];
-		if (isset($commit) && strlen($commit) > 1) {
-			$commitline = array();
-			$co = git_read_commit($projectroot . $project, $commit);
-			$ad = date_str($co['author_epoch']);
-			$commitline["project"] = $project;
-			$commitline["commit"] = $commit;
-			if (isset($refs[$commit]))
-				$commitline["commitref"] = $refs[$commit];
-			$commitline["agestring"] = $co['age_string'];
-			$commitline["title"] = $co['title'];
-			$commitline["authorname"] = $co['author_name'];
-			$commitline["rfc2822"] = $ad['rfc2822'];
-			$commitline["comment"] = $co['comment'];
-			$commitlines[] = $commitline;
-		}
-	}
-	$tpl->assign("commitlines",$commitlines);
-	$tpl->display("log.tpl");
+	$tpl->display('log.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_message.php
+++ b/include/display.git_message.php
@@ -10,12 +10,17 @@
 function git_message($message, $error = FALSE, $standalone = TRUE)
 {
 	global $tpl;
-	$tpl->assign("message",$message);
-	if ($error)
-		$tpl->assign("error", TRUE);
-	if ($standalone)
-		$tpl->assign("standalone", TRUE);
-	$tpl->display("message.tpl");
+
+	$cachekey = sha1($message) . "|" . ($error ? "1" : "0") . "|" . ($standalone ? "1" : "0");
+
+	if (!$tpl->is_cached('message.tpl', $cachekey)) {
+		$tpl->assign("message",$message);
+		if ($error)
+			$tpl->assign("error", TRUE);
+		if ($standalone)
+			$tpl->assign("standalone", TRUE);
+	}
+	$tpl->display('message.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_opml.php
+++ b/include/display.git_opml.php
@@ -13,22 +13,27 @@
 function git_opml($projectroot,$projectlist)
 {
 	global $tpl,$gitphp_conf;
-	$projlist = git_read_projects($projectroot,$projectlist);
-	header("Content-type: text/xml; charset=UTF-8");
-	$tpl->assign("title",$gitphp_conf['title']);
-	$tpl->assign("self",script_url());
-	$opmllist = array();
-	foreach ($projlist as $cat => $plist) {
-		if (is_array($plist)) {
-			foreach ($plist as $i => $proj) {
-				$opmllist[] = $proj;
+
+	$cachekey = sha1(serialize($projectlist));
+
+	if (!$tpl->is_cached('opml.tpl', $cachekey)) {
+		header("Content-type: text/xml; charset=UTF-8");
+		$projlist = git_read_projects($projectroot,$projectlist);
+		$tpl->assign("title",$gitphp_conf['title']);
+		$tpl->assign("self",script_url());
+		$opmllist = array();
+		foreach ($projlist as $cat => $plist) {
+			if (is_array($plist)) {
+				foreach ($plist as $i => $proj) {
+					$opmllist[] = $proj;
+				}
+			} else {
+				$opmllist[] = $plist;
 			}
-		} else {
-			$opmllist[] = $plist;
 		}
+		$tpl->assign("opmllist",$opmllist);
 	}
-	$tpl->assign("opmllist",$opmllist);
-	$tpl->display("opml.tpl");
+	$tpl->display('opml.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_project_list.php
+++ b/include/display.git_project_list.php
@@ -16,55 +16,60 @@
 function git_project_list($projectroot,$projectlist,$order = "project")
 {
 	global $tpl,$git_projects;
-	$projects = git_read_projects($projectroot,$projectlist, TRUE);
-	if (is_array($projects)) {
-		if (count($projects) > 0) {
-			if ($order)
-				$tpl->assign("order",$order);
-			if (!isset($git_projects)) {
-				switch ($order) {
-					case "project":
-						usort($projects,"projectcmp");
-						break;
-					case "descr":
-						usort($projects,"descrcmp");
-						break;
-					case "owner":
-						usort($projects,"ownercmp");
-						break;
-					case "age":
-						usort($projects,"agecmp");
-						break;
-				}
-				$tpl->assign("projects",$projects);
-			} else {
-				foreach ($projects as $cat => $plist) {
+
+	$cachekey = sha1(serialize($projectlist)) . "|" . sha1($order);
+
+	if (!$tpl->is_cached('projectlist.tpl', $cachekey)) {
+		$projects = git_read_projects($projectroot,$projectlist, TRUE);
+		if (is_array($projects)) {
+			if (count($projects) > 0) {
+				if ($order)
+					$tpl->assign("order",$order);
+				if (!isset($git_projects)) {
 					switch ($order) {
 						case "project":
-							usort($projects[$cat],"projectcmp");
+							usort($projects,"projectcmp");
 							break;
 						case "descr":
-							usort($projects[$cat],"descrcmp");
+							usort($projects,"descrcmp");
 							break;
 						case "owner":
-							usort($projects[$cat],"ownercmp");
+							usort($projects,"ownercmp");
 							break;
 						case "age":
-							usort($projects[$cat],"agecmp");
+							usort($projects,"agecmp");
 							break;
 					}
+					$tpl->assign("projects",$projects);
+				} else {
+					foreach ($projects as $cat => $plist) {
+						switch ($order) {
+							case "project":
+								usort($projects[$cat],"projectcmp");
+								break;
+							case "descr":
+								usort($projects[$cat],"descrcmp");
+								break;
+							case "owner":
+								usort($projects[$cat],"ownercmp");
+								break;
+							case "age":
+								usort($projects[$cat],"agecmp");
+								break;
+						}
+					}
+					$tpl->assign("categorizedprojects",$projects);
 				}
-				$tpl->assign("categorizedprojects",$projects);
+			} else {
+				$tpl->assign("message","No projects found");
+				$tpl->assign("error",TRUE);
 			}
 		} else {
-			$tpl->assign("message","No projects found");
+			$tpl->assign("message",$projects);
 			$tpl->assign("error",TRUE);
 		}
-	} else {
-		$tpl->assign("message",$projects);
-		$tpl->assign("error",TRUE);
 	}
-	$tpl->display("projectlist.tpl");
+	$tpl->display('projectlist.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_rss.php
+++ b/include/display.git_rss.php
@@ -18,41 +18,46 @@
 function git_rss($projectroot,$project)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	$revlist = git_read_revlist($projectroot . $project, $head, GITPHP_RSS_ITEMS);
 	header("Content-type: text/xml; charset=UTF-8");
-	$tpl->assign("self",script_url());
 
-	$commitlines = array();
-	for ($i = 0; $i <= count($revlist); $i++) {
-		$commit = $revlist[$i];
-		$co = git_read_commit($projectroot . $project, $commit);
-		if (($i >= 20) && ((time() - $co['committer_epoch']) > 48*60*60))
-			break;
-		$cd = date_str($co['committer_epoch']);
-		$difftree = array();
-		$diffout = git_diff_tree($projectroot . $project, $co['parent'] . " " . $co['id']);
-		$tok = strtok($diffout,"\n");
-		while ($tok !== false) {
-			if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$",$tok,$regs))
-				$difftree[] = $regs[7];
-			$tok = strtok("\n");
+	$cachekey = sha1($project);
+
+	if (!$tpl->is_cached('rss.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		$revlist = git_read_revlist($projectroot . $project, $head, GITPHP_RSS_ITEMS);
+		$tpl->assign("self",script_url());
+
+		$commitlines = array();
+		for ($i = 0; $i <= count($revlist); $i++) {
+			$commit = $revlist[$i];
+			$co = git_read_commit($projectroot . $project, $commit);
+			if (($i >= 20) && ((time() - $co['committer_epoch']) > 48*60*60))
+				break;
+			$cd = date_str($co['committer_epoch']);
+			$difftree = array();
+			$diffout = git_diff_tree($projectroot . $project, $co['parent'] . " " . $co['id']);
+			$tok = strtok($diffout,"\n");
+			while ($tok !== false) {
+				if (ereg("^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$",$tok,$regs))
+					$difftree[] = $regs[7];
+				$tok = strtok("\n");
+			}
+			$commitline = array();
+			$commitline["cdmday"] = $cd['mday'];
+			$commitline["cdmonth"] = $cd['month'];
+			$commitline["cdhour"] = $cd['hour'];
+			$commitline["cdminute"] = $cd['minute'];
+			$commitline["title"] = $co['title'];
+			$commitline["author"] = $co['author'];
+			$commitline["cdrfc2822"] = $cd['rfc2822'];
+			$commitline["commit"] = $commit;
+			$commitline["comment"] = $co['comment'];
+			$commitline["difftree"] = $difftree;
+			$commitlines[] = $commitline;
 		}
-		$commitline = array();
-		$commitline["cdmday"] = $cd['mday'];
-		$commitline["cdmonth"] = $cd['month'];
-		$commitline["cdhour"] = $cd['hour'];
-		$commitline["cdminute"] = $cd['minute'];
-		$commitline["title"] = $co['title'];
-		$commitline["author"] = $co['author'];
-		$commitline["cdrfc2822"] = $cd['rfc2822'];
-		$commitline["commit"] = $commit;
-		$commitline["comment"] = $co['comment'];
-		$commitline["difftree"] = $difftree;
-		$commitlines[] = $commitline;
+		$tpl->assign("commitlines",$commitlines);
 	}
-	$tpl->assign("commitlines",$commitlines);
-	$tpl->display("rss.tpl");
+	$tpl->display('rss.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_search.php
+++ b/include/display.git_search.php
@@ -17,67 +17,72 @@
 {
 	global $tpl,$gitphp_conf;
 
-	if (!$gitphp_conf['search']) {
-		git_message("Search has been disabled", TRUE, TRUE);
-		return;
+	$cachekey = sha1($project) . "|" . $hash . "|" . sha1($searchtype) . "|" . sha1($search) . "|" . $page;
+
+	if (!$tpl->is_cached('search.tpl', $cachekey)) {
+
+		if (!$gitphp_conf['search']) {
+			git_message("Search has been disabled", TRUE, TRUE);
+			return;
+		}
+
+		if (!isset($search) || (strlen($search) < 2)) {
+			git_message("You must enter search text of at least 2 characters", TRUE, TRUE);
+			return;
+		}
+		if (!isset($hash)) {
+			//$hash = git_read_head($projectroot . $project);
+			$hash = "HEAD";
+		}
+
+		$co = git_read_commit($projectroot . $project, $hash);
+
+		$revlist = explode("\n",trim(git_rev_list($projectroot . $project, $hash, 101, ($page * 100), FALSE, FALSE, $searchtype, $search)));
+		if (count($revlist) < 1 || (strlen($revlist[0]) < 1)) {
+			git_message("No matches for '" . $search . "'.", FALSE, TRUE);
+			return;
+		}
+
+		$tpl->assign("hash",$hash);
+		$tpl->assign("treehash",$co['tree']);
+
+		$tpl->assign("search",$search);
+		$tpl->assign("searchtype",$searchtype);
+		$tpl->assign("page",$page);
+		$revlistcount = count($revlist);
+		$tpl->assign("revlistcount",$revlistcount);
+
+		$tpl->assign("title",$co['title']);
+
+		$commitlines = array();
+		$commitcount = min(100,$revlistcount);
+		for ($i = 0; $i < $commitcount; $i++) {
+			$commit = $revlist[$i];
+			if (strlen(trim($commit)) > 0) {
+				$commitline = array();
+				$co2 = git_read_commit($projectroot . $project, $commit);
+				$commitline["commit"] = $commit;
+				$commitline["agestringage"] = $co2['age_string_age'];
+				$commitline["agestringdate"] = $co2['age_string_date'];
+				$commitline["authorname"] = $co2['author_name'];
+				$commitline["title_short"] = $co2['title_short'];
+				if (strlen($co2['title_short']) < strlen($co2['title']))
+					$commitline["title"] = $co2['title'];
+				$commitline["committree"] = $co2['tree'];
+				$matches = array();
+				foreach ($co2['comment'] as $comline) {
+					$hl = highlight($comline, $search, "searchmatch", GITPHP_TRIM_LENGTH);
+					if ($hl && (strlen($hl) > 0))
+						$matches[] = $hl;
+				}
+				$commitline["matches"] = $matches;
+				$commitlines[] = $commitline;
+			}
+		}
+		
+		$tpl->assign("commitlines",$commitlines);
 	}
-
-	if (!isset($search) || (strlen($search) < 2)) {
-		git_message("You must enter search text of at least 2 characters", TRUE, TRUE);
-		return;
-	}
-	if (!isset($hash)) {
-		//$hash = git_read_head($projectroot . $project);
-		$hash = "HEAD";
-	}
-
-	$co = git_read_commit($projectroot . $project, $hash);
-
-	$revlist = explode("\n",trim(git_rev_list($projectroot . $project, $hash, 101, ($page * 100), FALSE, FALSE, $searchtype, $search)));
-	if (count($revlist) < 1 || (strlen($revlist[0]) < 1)) {
-		git_message("No matches for '" . $search . "'.", FALSE, TRUE);
-		return;
-	}
-
-	$tpl->assign("hash",$hash);
-	$tpl->assign("treehash",$co['tree']);
-
-	$tpl->assign("search",$search);
-	$tpl->assign("searchtype",$searchtype);
-	$tpl->assign("page",$page);
-	$revlistcount = count($revlist);
-	$tpl->assign("revlistcount",$revlistcount);
-
-	$tpl->assign("title",$co['title']);
-
-	$commitlines = array();
-	$commitcount = min(100,$revlistcount);
-	for ($i = 0; $i < $commitcount; $i++) {
-		$commit = $revlist[$i];
-		if (strlen(trim($commit)) > 0) {
-			$commitline = array();
-			$co2 = git_read_commit($projectroot . $project, $commit);
-			$commitline["commit"] = $commit;
-			$commitline["agestringage"] = $co2['age_string_age'];
-			$commitline["agestringdate"] = $co2['age_string_date'];
-			$commitline["authorname"] = $co2['author_name'];
-			$commitline["title_short"] = $co2['title_short'];
-			if (strlen($co2['title_short']) < strlen($co2['title']))
-				$commitline["title"] = $co2['title'];
-			$commitline["committree"] = $co2['tree'];
-			$matches = array();
-			foreach ($co2['comment'] as $comline) {
-				$hl = highlight($comline, $search, "searchmatch", GITPHP_TRIM_LENGTH);
-				if ($hl && (strlen($hl) > 0))
-					$matches[] = $hl;
-			}
-			$commitline["matches"] = $matches;
-			$commitlines[] = $commitline;
-		}
-	}
-	
-	$tpl->assign("commitlines",$commitlines);
-	$tpl->display("search.tpl");
+	$tpl->display('search.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_search_files.php
+++ b/include/display.git_search_files.php
@@ -17,79 +17,84 @@
 {
 	global $tpl,$gitphp_conf;
 
-	if (!($gitphp_conf['search'] && $gitphp_conf['filesearch'])) {
-		git_message("File search has been disabled", TRUE, TRUE);
-		return;
+	$cachekey = sha1($project) . "|" . $hash . "|" . "filesearch" . "|" . sha1($search) . "|" . $page;
+
+	if (!$tpl->is_cached('searchfiles.tpl', $cachekey)) {
+
+		if (!($gitphp_conf['search'] && $gitphp_conf['filesearch'])) {
+			git_message("File search has been disabled", TRUE, TRUE);
+			return;
+		}
+
+		if (!isset($search) || (strlen($search) < 2)) {
+			git_message("You must enter search text of at least 2 characters", TRUE, TRUE);
+			return;
+		}
+		if (!isset($hash)) {
+			//$hash = git_read_head($projectroot . $project);
+			$hash = "HEAD";
+		}
+
+		$co = git_read_commit($projectroot . $project, $hash);
+
+		$filesearch = git_filesearch($projectroot . $project, $hash, $search, false, ($page * 100), 101);
+
+		if (count($filesearch) < 1) {
+			git_message("No matches for '" . $search . "'.", FALSE, TRUE);
+			return;
+		}
+
+		$tpl->assign("hash",$hash);
+		$tpl->assign("treehash",$co['tree']);
+
+		$tpl->assign("search",$search);
+		$tpl->assign("searchtype","file");
+		$tpl->assign("page",$page);
+		$filesearchcount = count($filesearch);
+		$tpl->assign("filesearchcount",$filesearchcount);
+
+		$tpl->assign("title",$co['title']);
+
+		$filesearchlines = array();
+		$i = 0;
+		foreach ($filesearch as $file => $data) {
+			$filesearchline = array();
+			$filesearchline["file"] = $file;
+			if (strpos($file,"/") !== false) {
+				$f = basename($file);
+				$d = dirname($file);
+				if ($d == "/")
+					$d = "";
+				$hlt = highlight($f, $search, "searchmatch");
+				if ($hlt)
+					$hlt = $d . "/" . $hlt;
+			} else
+				$hlt = highlight($file, $search, "searchmatch");
+			if ($hlt)
+				$filesearchline["filename"] = $hlt;
+			else
+				$filesearchline["filename"] = $file;
+			$filesearchline["hash"] = $data['hash'];
+			if ($data['type'] == "tree")
+				$filesearchline["tree"] = TRUE;
+			if (isset($data['lines'])) {
+				$matches = array();
+				foreach ($data['lines'] as $line) {
+					$hlt = highlight($line,$search,"searchmatch",floor(GITPHP_TRIM_LENGTH*1.5),true);
+					if ($hlt)
+						$matches[] = $hlt;
+				}
+				if (count($matches) > 0)
+					$filesearchline["matches"] = $matches;
+			}
+			$filesearchlines[] = $filesearchline;
+			$i++;
+			if ($i >= 100)
+				break;
+		}
+		$tpl->assign("filesearchlines",$filesearchlines);
 	}
-
-	if (!isset($search) || (strlen($search) < 2)) {
-		git_message("You must enter search text of at least 2 characters", TRUE, TRUE);
-		return;
-	}
-	if (!isset($hash)) {
-		//$hash = git_read_head($projectroot . $project);
-		$hash = "HEAD";
-	}
-
-	$co = git_read_commit($projectroot . $project, $hash);
-
-	$filesearch = git_filesearch($projectroot . $project, $hash, $search, false, ($page * 100), 101);
-
-	if (count($filesearch) < 1) {
-		git_message("No matches for '" . $search . "'.", FALSE, TRUE);
-		return;
-	}
-
-	$tpl->assign("hash",$hash);
-	$tpl->assign("treehash",$co['tree']);
-
-	$tpl->assign("search",$search);
-	$tpl->assign("searchtype","file");
-	$tpl->assign("page",$page);
-	$filesearchcount = count($filesearch);
-	$tpl->assign("filesearchcount",$filesearchcount);
-
-	$tpl->assign("title",$co['title']);
-
-	$filesearchlines = array();
-	$i = 0;
-	foreach ($filesearch as $file => $data) {
-		$filesearchline = array();
-		$filesearchline["file"] = $file;
-		if (strpos($file,"/") !== false) {
-			$f = basename($file);
-			$d = dirname($file);
-			if ($d == "/")
-				$d = "";
-			$hlt = highlight($f, $search, "searchmatch");
-			if ($hlt)
-				$hlt = $d . "/" . $hlt;
-		} else
-			$hlt = highlight($file, $search, "searchmatch");
-		if ($hlt)
-			$filesearchline["filename"] = $hlt;
-		else
-			$filesearchline["filename"] = $file;
-		$filesearchline["hash"] = $data['hash'];
-		if ($data['type'] == "tree")
-			$filesearchline["tree"] = TRUE;
-		if (isset($data['lines'])) {
-			$matches = array();
-			foreach ($data['lines'] as $line) {
-				$hlt = highlight($line,$search,"searchmatch",floor(GITPHP_TRIM_LENGTH*1.5),true);
-				if ($hlt)
-					$matches[] = $hlt;
-			}
-			if (count($matches) > 0)
-				$filesearchline["matches"] = $matches;
-		}
-		$filesearchlines[] = $filesearchline;
-		$i++;
-		if ($i >= 100)
-			break;
-	}
-	$tpl->assign("filesearchlines",$filesearchlines);
-	$tpl->display("searchfiles.tpl");
+	$tpl->display('searchfiles.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_shortlog.php
+++ b/include/display.git_shortlog.php
@@ -16,45 +16,50 @@
 function git_shortlog($projectroot,$project,$hash,$page)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	if (!isset($hash))
-		$hash = $head;
-	if (!isset($page))
-		$page = 0;
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	$tpl->assign("head",$head);
 
-	if ($page)
-		$tpl->assign("page",$page);
+	$cachekey = sha1($project) . "|" . $hash . "|" . $page;
 
-	$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100));
+	if (!$tpl->is_cached('shortlog.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		if (!isset($hash))
+			$hash = $head;
+		if (!isset($page))
+			$page = 0;
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		$tpl->assign("head",$head);
 
-	$revlistcount = count($revlist);
-	$tpl->assign("revlistcount",$revlistcount);
+		if ($page)
+			$tpl->assign("page",$page);
 
-	$commitlines = array();
-	$commitcount = min(100,count($revlist));
-	for ($i = 0; $i < $commitcount; $i++) {
-		$commit = $revlist[$i];
-		if (strlen(trim($commit)) > 0) {
-			$commitline = array();
-			if (isset($refs[$commit]))
-				$commitline["commitref"] = $refs[$commit];
-			$co = git_read_commit($projectroot . $project, $commit);
-			$ad = date_str($co['author_epoch']);
-			$commitline["commit"] = $commit;
-			$commitline["agestringage"] = $co['age_string_age'];
-			$commitline["agestringdate"] = $co['age_string_date'];
-			$commitline["authorname"] = $co['author_name'];
-			$commitline["title_short"] = $co['title_short'];
-			if (strlen($co['title_short']) < strlen($co['title']))
-				$commitline["title"] = $co['title'];
-			$commitlines[] = $commitline;
+		$revlist = git_read_revlist($projectroot . $project, $hash, 101, ($page * 100));
+
+		$revlistcount = count($revlist);
+		$tpl->assign("revlistcount",$revlistcount);
+
+		$commitlines = array();
+		$commitcount = min(100,count($revlist));
+		for ($i = 0; $i < $commitcount; $i++) {
+			$commit = $revlist[$i];
+			if (strlen(trim($commit)) > 0) {
+				$commitline = array();
+				if (isset($refs[$commit]))
+					$commitline["commitref"] = $refs[$commit];
+				$co = git_read_commit($projectroot . $project, $commit);
+				$ad = date_str($co['author_epoch']);
+				$commitline["commit"] = $commit;
+				$commitline["agestringage"] = $co['age_string_age'];
+				$commitline["agestringdate"] = $co['age_string_date'];
+				$commitline["authorname"] = $co['author_name'];
+				$commitline["title_short"] = $co['title_short'];
+				if (strlen($co['title_short']) < strlen($co['title']))
+					$commitline["title"] = $co['title'];
+				$commitlines[] = $commitline;
+			}
 		}
+		$tpl->assign("commitlines",$commitlines);
 	}
-	$tpl->assign("commitlines",$commitlines);
-	$tpl->display("shortlog.tpl");
+	$tpl->display('shortlog.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_summary.php
+++ b/include/display.git_summary.php
@@ -19,53 +19,58 @@
 function git_summary($projectroot,$project)
 {
 	global $tpl;
-	$descr = git_project_descr($projectroot,$project);
-	$head = git_read_head($projectroot . $project);
-	$commit = git_read_commit($projectroot . $project, $head);
-	$commitdate = date_str($commit['committer_epoch'],$commit['committer_tz']);
-	$owner = git_project_owner($projectroot,$project);
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("head",$head);
-	$tpl->assign("description",$descr);
-	$tpl->assign("owner",$owner);
-	$tpl->assign("lastchange",$commitdate['rfc2822']);
-	$revlist = git_read_revlist($projectroot . $project, $head, 17);
-	foreach ($revlist as $i => $rev) {
-		$revdata = array();
-		$revco = git_read_commit($projectroot . $project, $rev);
-		$authordate = date_str($revco['author_epoch']);
-		$revdata["commit"] = $rev;
-		if (isset($refs[$rev]))
-			$revdata["commitref"] = $refs[$rev];
-		$revdata["commitage"] = $revco['age_string'];
-		$revdata["commitauthor"] = $revco['author_name'];
-		if (strlen($revco['title_short']) < strlen($revco['title'])) {
-			$revdata["title"] = $revco['title'];
-			$revdata["title_short"] = $revco['title_short'];
-		} else
-			$revdata["title_short"] = $revco['title'];
-		$revlist[$i] = $revdata;
+
+	$cachekey = sha1($project);
+
+	if (!$tpl->is_cached('project.tpl', $cachekey)) {
+		$descr = git_project_descr($projectroot,$project);
+		$head = git_read_head($projectroot . $project);
+		$commit = git_read_commit($projectroot . $project, $head);
+		$commitdate = date_str($commit['committer_epoch'],$commit['committer_tz']);
+		$owner = git_project_owner($projectroot,$project);
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("head",$head);
+		$tpl->assign("description",$descr);
+		$tpl->assign("owner",$owner);
+		$tpl->assign("lastchange",$commitdate['rfc2822']);
+		$revlist = git_read_revlist($projectroot . $project, $head, 17);
+		foreach ($revlist as $i => $rev) {
+			$revdata = array();
+			$revco = git_read_commit($projectroot . $project, $rev);
+			$authordate = date_str($revco['author_epoch']);
+			$revdata["commit"] = $rev;
+			if (isset($refs[$rev]))
+				$revdata["commitref"] = $refs[$rev];
+			$revdata["commitage"] = $revco['age_string'];
+			$revdata["commitauthor"] = $revco['author_name'];
+			if (strlen($revco['title_short']) < strlen($revco['title'])) {
+				$revdata["title"] = $revco['title'];
+				$revdata["title_short"] = $revco['title_short'];
+			} else
+				$revdata["title_short"] = $revco['title'];
+			$revlist[$i] = $revdata;
+		}
+		$tpl->assign("revlist",$revlist);
+
+		$taglist = git_read_refs($projectroot,$project,"refs/tags");
+		if (isset($taglist) && (count($taglist) > 0)) {
+			foreach ($taglist as $i => $tag) {
+				if (isset($tag['comment'])) {
+					$com = trim($tag['comment'][0]);
+					if (strlen($com) > GITPHP_TRIM_LENGTH)
+						$com = substr($trimmed,0,GITPHP_TRIM_LENGTH) . "...";
+					$taglist[$i]['comment'] = $com;
+				}
+			}
+			$tpl->assign("taglist",$taglist);
+		}
+
+		$headlist = git_read_refs($projectroot,$project,"refs/heads");
+		if (isset($headlist) && (count($headlist) > 0)) {
+			$tpl->assign("headlist",$headlist);
+		}
 	}
-	$tpl->assign("revlist",$revlist);
-
-	$taglist = git_read_refs($projectroot,$project,"refs/tags");
-	if (isset($taglist) && (count($taglist) > 0)) {
-		foreach ($taglist as $i => $tag) {
-			if (isset($tag['comment'])) {
-				$com = trim($tag['comment'][0]);
-				if (strlen($com) > GITPHP_TRIM_LENGTH)
-					$com = substr($trimmed,0,GITPHP_TRIM_LENGTH) . "...";
-				$taglist[$i]['comment'] = $com;
-			}
-		}
-		$tpl->assign("taglist",$taglist);
-	}
-
-	$headlist = git_read_refs($projectroot,$project,"refs/heads");
-	if (isset($headlist) && (count($headlist) > 0)) {
-		$tpl->assign("headlist",$headlist);
-	}
-	$tpl->display("project.tpl");
+	$tpl->display('project.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_tag.php
+++ b/include/display.git_tag.php
@@ -15,18 +15,23 @@
 {
 	global $tpl;
 
-	$head = git_read_head($projectroot . $project);
-	$tpl->assign("head",$head);
-	$tpl->assign("hash", $hash);
+	$cachekey = sha1($project) . "|" . $hash;
 
-	$tag = git_read_tag($projectroot . $project, $hash);
+	if (!$tpl->is_cached('tag.tpl', $cachekey)) {
 
-	$tpl->assign("tag",$tag);
-	if (isset($tag['author'])) {
-		$ad = date_str($tag['epoch'],$tag['tz']);
-		$tpl->assign("datedata",$ad);
+		$head = git_read_head($projectroot . $project);
+		$tpl->assign("head",$head);
+		$tpl->assign("hash", $hash);
+
+		$tag = git_read_tag($projectroot . $project, $hash);
+
+		$tpl->assign("tag",$tag);
+		if (isset($tag['author'])) {
+			$ad = date_str($tag['epoch'],$tag['tz']);
+			$tpl->assign("datedata",$ad);
+		}
 	}
-	$tpl->display("tag.tpl");
+	$tpl->display('tag.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_tags.php
+++ b/include/display.git_tags.php
@@ -13,13 +13,18 @@
 function git_tags($projectroot,$project)
 {
 	global $tpl;
-	$head = git_read_head($projectroot . $project);
-	$tpl->assign("head",$head);
-	$taglist = git_read_refs($projectroot, $project, "refs/tags");
-	if (isset($taglist) && (count($taglist) > 0)) {
-		$tpl->assign("taglist",$taglist);
+
+	$cachekey = sha1($project);
+
+	if (!$tpl->is_cached('tags.tpl', $cachekey)) {
+		$head = git_read_head($projectroot . $project);
+		$tpl->assign("head",$head);
+		$taglist = git_read_refs($projectroot, $project, "refs/tags");
+		if (isset($taglist) && (count($taglist) > 0)) {
+			$tpl->assign("taglist",$taglist);
+		}
 	}
-	$tpl->display("tags.tpl");
+	$tpl->display('tags.tpl', $cachekey);
 }
 
 ?>

--- a/include/display.git_tree.php
+++ b/include/display.git_tree.php
@@ -18,46 +18,51 @@
 function git_tree($projectroot,$project,$hash,$file,$hashbase)
 {
 	global $tpl;
-	if (!isset($hash)) {
-		$hash = git_read_head($projectroot . $project);
+
+	$cachekey = sha1($project) . "|" . $hashbase . "|" . $hash . "|" . sha1($file);
+
+	if (!$tpl->is_cached('tree.tpl', $cachekey)) {
+		if (!isset($hash)) {
+			$hash = git_read_head($projectroot . $project);
+			if (isset($file))
+				$hash = git_get_hash_by_path($projectroot . $project, ($hashbase?$hashbase:$hash),$file,"tree");
+				if (!isset($hashbase))
+					$hashbase = $hash;
+		}
+		$lsout = git_ls_tree($projectroot . $project, $hash, TRUE);
+		$refs = read_info_ref($projectroot . $project);
+		$tpl->assign("hash",$hash);
+		if (isset($hashbase))
+			$tpl->assign("hashbase",$hashbase);
+		if (isset($hashbase) && ($co = git_read_commit($projectroot . $project, $hashbase))) {
+			$basekey = $hashbase;
+			$tpl->assign("fullnav",TRUE);
+			$tpl->assign("title",$co['title']);
+			if (isset($refs[$hashbase]))
+				$tpl->assign("hashbaseref",$refs[$hashbase]);
+		}
+		$paths = git_path_trees($projectroot . $project, $hashbase, $file);
+		$tpl->assign("paths",$paths);
+
 		if (isset($file))
-			$hash = git_get_hash_by_path($projectroot . $project, ($hashbase?$hashbase:$hash),$file,"tree");
-			if (!isset($hashbase))
-				$hashbase = $hash;
+			$tpl->assign("base",$file . "/");
+
+		$treelines = array();
+		$tok = strtok($lsout,"\0");
+		while ($tok !== false) {
+			if (ereg("^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$",$tok,$regs)) {
+				$treeline = array();
+				$treeline["filemode"] = mode_str($regs[1]);
+				$treeline["type"] = $regs[2];
+				$treeline["hash"] = $regs[3];
+				$treeline["name"] = $regs[4];
+				$treelines[] = $treeline;
+			}
+			$tok = strtok("\0");
+		}
+		$tpl->assign("treelines",$treelines);
 	}
-	$lsout = git_ls_tree($projectroot . $project, $hash, TRUE);
-	$refs = read_info_ref($projectroot . $project);
-	$tpl->assign("hash",$hash);
-	if (isset($hashbase))
-		$tpl->assign("hashbase",$hashbase);
-	if (isset($hashbase) && ($co = git_read_commit($projectroot . $project, $hashbase))) {
-		$basekey = $hashbase;
-		$tpl->assign("fullnav",TRUE);
-		$tpl->assign("title",$co['title']);
-		if (isset($refs[$hashbase]))
-			$tpl->assign("hashbaseref",$refs[$hashbase]);
-	}
-	$paths = git_path_trees($projectroot . $project, $hashbase, $file);
-	$tpl->assign("paths",$paths);
-
-	if (isset($file))
-		$tpl->assign("base",$file . "/");
-
-	$treelines = array();
-	$tok = strtok($lsout,"\0");
-	while ($tok !== false) {
-		if (ereg("^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$",$tok,$regs)) {
-			$treeline = array();
-			$treeline["filemode"] = mode_str($regs[1]);
-			$treeline["type"] = $regs[2];
-			$treeline["hash"] = $regs[3];
-			$treeline["name"] = $regs[4];
-			$treelines[] = $treeline;
-		}
-		$tok = strtok("\0");
-	}
-	$tpl->assign("treelines",$treelines);
-	$tpl->display("tree.tpl");
+	$tpl->display('tree.tpl', $cachekey);
 }
 
 ?>

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -47,6 +47,14 @@
 		define('GITPHP_START_TIME', microtime(true));
 		error_reporting(E_ALL|E_STRICT);
 	}
+ }
+
+/*
+ * Caching
+ */
+ if ($gitphp_conf['cache']) {
+ 	$tpl->caching = 2;
+	$tpl->cache_lifetime = $gitphp_conf['cachelifetime'];
  }
 
 /*

comments