Make sure we always expire cache unless user very explicitly turns it off by setting it to false
Make sure we always expire cache unless user very explicitly turns it off by setting it to false

file:a/README -> file:b/README
--- a/README
+++ b/README
@@ -79,3 +79,47 @@
 If you want to edit the text header that appears above the project list on the
 home page, edit templates/hometext.tpl.
 
+
+[Caching]
+
+To turn on caching, set the 'cache' config item to true.  Gitphp will cache
+every page's output, including plaintext output and binary output such as
+blobs and snapshots, for the number of seconds specified in the
+'cachelifetime' config key.
+The 'cacheexpire' key is recommended for most users.  With this option on,
+gitphp will attempt to keep the cache in sync by automatically expiring any
+cached pages that are older than the most recent commit, on any branch.
+It is a slight performance hit to make this check, but the performance hit
+is tiny compared to the gain you get from turning on caching.  It will
+avoid situations where users are getting a cached version of a page that
+isn't up to date and doesn't reflect the most recent commit, or worse,
+pages that have been cached at different times and show data from both
+before and after a commit (eg page 1 of the shortlog shows the most recent
+commit but page 1 of the log was cached a while ago and doesn't show the
+most recent commit).
+However, if your project is so active that commits are constantly coming in
+and invalidating the cache, rendering it useless, it would be better to
+turn cache expiration off and just set a really short cache lifetime of
+a few seconds.  In other words:
+
+Most users:
+* Set 'cacheexpire' to TRUE
+* Set 'cachelifetime' high, 3600 seconds (1 hour) or more.  -1 means
+  cache forever
+
+Extremely active projects, with commits every few seconds, or advanced
+users that know exactly how often commits come in and want to save
+the performance of the expiration check:
+* Set 'cacheexpire' to FALSE
+* Set 'cachelifetime' low, between 5-10 seconds.
+
+If you ever run into problems with your cache not syncing correctly, or
+showing out of date information, you can use the 'expire' action to force
+expiration of all cache.  This action is not linked anywhere because it
+is not supposed to be run by users, it's more of an administrative function.
+To use it, you want to set a=expire.  So, for example, you would visit this
+address in a browser (obviously with the correct path to your gitphp
+index.php):
+
+http://yourserver.com/gitphp/index.php?a=expire
+

--- a/config/gitphp.conf.php.example
+++ b/config/gitphp.conf.php.example
@@ -202,7 +202,7 @@
  * relatively high - 3600 seconds (1 hour) or even longer.
  * -1 means no timeout.
  * If you have turned cacheexpire off because of too many
- * cache expirations, set this low, like 3-5 seconds.
+ * cache expirations, set this low (5-10 seconds).
  */
 $gitphp_conf['cachelifetime'] = 3600;
 

--- a/include/display.git_commitdiff_plain.php
+++ b/include/display.git_commitdiff_plain.php
@@ -12,7 +12,7 @@
  require_once('util.script_url.php');
  require_once('gitutil.git_read_commit.php');
  require_once('gitutil.git_diff_tree.php');
- require_once('gitutil.git_rev_list.php');
+ require_once('gitutil.git_read_revlist.php');
  require_once('gitutil.read_info_ref.php');
  require_once('gitutil.git_diff.php');
 
@@ -37,14 +37,12 @@
 		$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)
+		$listout = git_read_revlist($projectroot . $project, "HEAD");
+		foreach ($listout as $i => $rev) {
+			if (isset($refs[$rev]))
+				$tagname = $refs[$rev];
+			if ($rev == $hash)
 				break;
-			$tok = strtok("\n");
 		}
 		$ad = date_str($co['author_epoch'],$co['author_tz']);
 		$tpl->assign("from",$co['author']);

--- a/include/display.git_rss.php
+++ b/include/display.git_rss.php
@@ -28,7 +28,7 @@
 		$tpl->assign("self",script_url());
 
 		$commitlines = array();
-		for ($i = 0; $i <= count($revlist); $i++) {
+		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))

--- a/include/display.git_search.php
+++ b/include/display.git_search.php
@@ -10,7 +10,7 @@
 require_once('defs.constants.php');
 require_once('util.highlight.php');
 require_once('gitutil.git_read_commit.php');
-require_once('gitutil.git_rev_list.php');
+require_once('gitutil.git_read_revlist.php');
 require_once('display.git_message.php');
 
 function git_search($projectroot, $project, $hash, $search, $searchtype, $page = 0)
@@ -37,7 +37,7 @@
 
 		$co = git_read_commit($projectroot . $project, $hash);
 
-		$revlist = explode("\n",trim(git_rev_list($projectroot . $project, $hash, 101, ($page * 100), FALSE, FALSE, $searchtype, $search)));
+		$revlist = git_read_revlist($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;

--- a/include/gitutil.git_exec_nix.php
+++ b/include/gitutil.git_exec_nix.php
@@ -10,7 +10,10 @@
  function git_exec_nix($project, $command)
  {
  	global $gitphp_conf;
-	$cmd = $gitphp_conf['gitbin'] . " --git-dir=" . $project . " " . $command;
+	$cmd = $gitphp_conf['gitbin'];
+	if (isset($project) && (strlen($project) > 0))
+		$cmd .= " --git-dir=" . $project;
+	$cmd .= " " . $command;
 	return shell_exec($cmd);
  }
 

--- a/include/gitutil.git_exec_win.php
+++ b/include/gitutil.git_exec_win.php
@@ -10,7 +10,10 @@
 function git_exec_win($project, $command)
 {
 	global $gitphp_conf;
-	$cmd = $gitphp_conf['gitbin'] . " --git-dir=" . $project . " " . $command;
+	$cmd = $gitphp_conf['gitbin'];
+	if (isset($project) && (strlen($project) > 0))
+		$cmd .= " --git-dir=" . $project;
+	$cmd .= " " . $command;
 	return shell_exec($cmd);
 }
 

--- a/include/gitutil.git_read_commit.php
+++ b/include/gitutil.git_read_commit.php
@@ -9,12 +9,11 @@
 
  require_once('defs.constants.php');
  require_once('util.age_string.php');
- require_once('gitutil.git_rev_list.php');
+ require_once('gitutil.git_read_revlist.php');
 
 function git_read_commit($proj,$head)
 {
-	$revlist = git_rev_list($proj,$head,1,NULL,TRUE,TRUE);
-	$lines = explode("\n",$revlist);
+	$lines = git_read_revlist($proj,$head,1,NULL,TRUE,TRUE);
 	if (!($lines[0]) || !ereg("^[0-9a-fA-F]{40}",$lines[0]))
 		return null;
 	$commit = array();

--- a/include/gitutil.git_read_revlist.php
+++ b/include/gitutil.git_read_revlist.php
@@ -8,11 +8,39 @@
  */
 
  require_once('gitutil.git_rev_list.php');
+ require_once('gitutil.git_version.php');
 
-function git_read_revlist($proj,$head,$count,$skip = NULL)
+function git_read_revlist($proj,$head,$count = NULL,$skip = NULL,$header = FALSE,$parents = FALSE,$greptype = NULL, $search = NULL)
 {
-	$revs = trim(git_rev_list($proj,$head,$count, $skip));
+	$passedskip = $skip;
+	$passedcount = $count;
+	$canskip = true;
+
+	if (isset($skip) && ($skip > 0)) {
+		$version = git_version();
+		if (isset($version) && (strlen($version) > 0)) {
+			$splitver = explode(".",$version);
+
+			/* Skip only appears in git >= 1.5.0 */
+			if (($splitver[0] < 1) || (($splitver[0] == 1) && ($splitver[1] < 5))) {
+				$canskip = false;
+				$passedskip = null;
+				$passedcount += $skip;
+			}
+		}
+	}
+
+	$revs = trim(git_rev_list($proj,$head, $passedcount, $passedskip, $header, $parents, $greptype, $search));
 	$revlist = explode("\n",$revs);
+
+	if ((!$canskip) && ($skip > 0)) {
+		$tmp = array();
+		$revcount = count($revlist);
+		for ($i = $skip; $i < $revcount; $i++)
+			$tmp[] = $revlist[$i];
+		return $tmp;
+	}
+
 	return $revlist;
 }
 

--- /dev/null
+++ b/include/gitutil.git_version.php
@@ -1,1 +1,21 @@
+<?php
+/*
+ *  gitutil.git_version.php
+ *  gitphp: A PHP git repository browser
+ *  Component: Git utility - version
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+ require_once('gitutil.git_exec.php');
+
+ function git_version()
+ {
+ 	$verstr = explode(" ",git_exec(null, "--version"));
+	if (($verstr[0] == "git") && ($verstr[1] == "version"))
+		return $verstr[2];
+	return null;
+ }
+
+?>
+

--- a/include/version.php
+++ b/include/version.php
@@ -7,7 +7,7 @@
  *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
  */
 
- $gitphp_version = "0.0.7";
+ $gitphp_version = "0.0.8";
  $gitphp_appstring = "gitphp $gitphp_version";
 
 ?>

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -56,7 +56,7 @@
  if ($gitphp_conf['cache']) {
  	$tpl->caching = 2;
 	$tpl->cache_lifetime = $gitphp_conf['cachelifetime'];
-	if ($gitphp_conf['cacheexpire']) {
+	if (!(isset($gitphp_conf['cacheexpire']) && ($gitphp_conf['cacheexpire'] === FALSE))) {
 		require_once('include/cache.cache_expire.php');
 		cache_expire($gitphp_conf['projectroot'], (isset($_GET['p']) ? $_GET['p'] : null), $git_projects);
 	}
@@ -98,7 +98,7 @@
  	require_once('include/cache.cache_expire.php');
 	require_once('include/display.git_message.php');
 	cache_expire(null, null, null, true);
-	git_message("Cache expired", true);
+	git_message("Cache expired");
  } else if (isset($_GET['a']) && $_GET['a'] == "opml") {
 	require_once('include/display.git_opml.php');
 	git_opml($gitphp_conf['projectroot'],$git_projects);

comments