Use the shared smarty cache instead of handling it manually
Use the shared smarty cache instead of handling it manually

This cuts down the code and allows us to use memcache if configured.
Since the list of projects is background-level data (and not HTML
pages), it uses the object cache. But since it's not immutable like git
objects, the lifetime uses the regular cache lifetime setting, which is
generally set shorter than the object cache lifetime (that could even be
set to -1).

--- a/config/gitphp.conf.defaults.php
+++ b/config/gitphp.conf.defaults.php
@@ -394,11 +394,18 @@
 
 /*
  * debug
- * Turns on extra warning messages and benchmarking.
+ * Turns on extra warning messages
  * Not recommended for production systems, as it will give
- * way more benchmarking info than you care about, and
+ * way more info about what's happening than you care about, and
  * will screw up non-html output (rss, opml, snapshots, etc)
  */
 $gitphp_conf['debug'] = false;
 
-
+/*
+ * benchmark
+ * Turns on extra timestamp and memory benchmarking info
+ * when debug mode is turned on.  Generates lots of output.
+ */
+$gitphp_conf['benchmark'] = false;
+
+

--- a/config/projects.conf.php.example
+++ b/config/projects.conf.php.example
@@ -87,6 +87,12 @@
  *	     setting in the config for this project.  This can also be
  *	     an empty string to override the global bug url to say that
  *	     only this project has no bug url.
+ *
+ * 'compat': whether this project runs in compatibility mode.  (true/false)
+ *	     This overrides the compat setting in the config for this project.
+ *	     Compatibility mode relies more on the git executable for loading
+ *	     data, at the expense of performance.  Use if you are having
+ *	     trouble loading data for this project.
  */
 //$git_projects_settings['php/gitphp.git'] = array(
 //	'category' => 'PHP',
@@ -95,10 +101,12 @@
 //	'cloneurl' => 'http://git.xiphux.com/php/gitphp.git',
 //	'pushurl' => '',
 //	'bugpattern' => '/#([0-9]+)/',
-//	'bugurl' => 'http://mantis.xiphux.com/view.php?id=${1}'
+//	'bugurl' => 'http://mantis.xiphux.com/view.php?id=${1}',
+//	'compat' => false
 //);
 //$git_projects_settings['gentoo.git'] = array(
-//	'description' => 'Gentoo portage overlay'
+//	'description' => 'Gentoo portage overlay',
+//	'compat' => true
 //);
 //$git_projects_settings['core/fbx.git'] = array(
 //	'description' => 'FBX music player',

--- a/include/Log.class.php
+++ b/include/Log.class.php
@@ -36,6 +36,15 @@
 	protected $enabled = false;
 
 	/**
+	 * benchmark
+	 *
+	 * Stores whether benchmarking is enabled
+	 *
+	 * @access protected
+	 */
+	protected $benchmark = false;
+
+	/**
 	 * startTime
 	 *
 	 * Stores the starting instant
@@ -94,6 +103,7 @@
 		$this->startMem = memory_get_usage();
 
 		$this->enabled = GitPHP_Config::GetInstance()->GetValue('debug', false);
+		$this->benchmark = GitPHP_Config::GetInstance()->GetValue('benchmark', false);
 	}
 
 	/**
@@ -136,8 +146,12 @@
 			return;
 
 		$entry = array();
-		$entry['time'] = microtime(true);
-		$entry['mem'] = memory_get_usage();
+		
+		if ($this->benchmark) {
+			$entry['time'] = microtime(true);
+			$entry['mem'] = memory_get_usage();
+		}
+
 		$entry['msg'] = $message;
 		$this->entries[] = $entry;
 	}
@@ -166,6 +180,32 @@
 	public function SetEnabled($enable)
 	{
 		$this->enabled = $enable;
+	}
+
+	/**
+	 * GetBenchmark
+	 *
+	 * Gets whether benchmarking is enabled
+	 *
+	 * @access public
+	 * @return boolean true if benchmarking is enabled
+	 */
+	public function GetBenchmark()
+	{
+		return $this->benchmark;
+	}
+
+	/**
+	 * SetBenchmark
+	 *
+	 * Sets whether benchmarking is enabled
+	 *
+	 * @access public
+	 * @param boolean $bench true if benchmarking is enabled
+	 */
+	public function SetBenchmark($bench)
+	{
+		$this->benchmark = $bench;
 	}
 
 	/**
@@ -181,21 +221,31 @@
 		$data = array();
 	
 		if ($this->enabled) {
-			$endTime = microtime(true);
-			$endMem = memory_get_usage();
-
-			$lastTime = $this->startTime;
-			$lastMem = $this->startMem;
-
-			$data[] = '[' . $this->startTime . '] [' . $this->startMem . ' bytes] Start';
+
+			if ($this->benchmark) {
+				$endTime = microtime(true);
+				$endMem = memory_get_usage();
+
+				$lastTime = $this->startTime;
+				$lastMem = $this->startMem;
+
+				$data[] = 'DEBUG: [' . $this->startTime . '] [' . $this->startMem . ' bytes] Start';
+
+			}
 
 			foreach ($this->entries as $entry) {
-				$data[] = '[' . $entry['time'] . '] [' . ($entry['time'] - $this->startTime) . ' sec since start] [' . ($entry['time'] - $lastTime) . ' sec since last] [' . $entry['mem'] . ' bytes] [' . ($entry['mem'] - $this->startMem) . ' bytes since start] [' . ($entry['mem'] - $lastMem) . ' bytes since last] ' . $entry['msg'];
-				$lastTime = $entry['time'];
-				$lastMem = $entry['mem'];
+				if ($this->benchmark) {
+					$data[] = 'DEBUG: [' . $entry['time'] . '] [' . ($entry['time'] - $this->startTime) . ' sec since start] [' . ($entry['time'] - $lastTime) . ' sec since last] [' . $entry['mem'] . ' bytes] [' . ($entry['mem'] - $this->startMem) . ' bytes since start] [' . ($entry['mem'] - $lastMem) . ' bytes since last] ' . $entry['msg'];
+					$lastTime = $entry['time'];
+					$lastMem = $entry['mem'];
+				} else {
+					$data[] = 'DEBUG: ' . $entry['msg'];
+				}
 			}
 
-			$data[] = '[' . $endTime . '] [' . ($endTime - $this->startTime) . ' sec since start] [' . ($endTime - $lastTime) . ' sec since last] [' . $endMem . ' bytes] [' . ($endMem - $this->startMem) . ' bytes since start] [' . ($endMem - $lastMem) . ' bytes since last] End';
+			if ($this->benchmark) {
+				$data[] = '[' . $endTime . '] [' . ($endTime - $this->startTime) . ' sec since start] [' . ($endTime - $lastTime) . ' sec since last] [' . $endMem . ' bytes] [' . ($endMem - $this->startMem) . ' bytes since start] [' . ($endMem - $lastMem) . ' bytes since last] End';
+			}
 		}
 
 		return $data;

--- a/include/cache/Cache.class.php
+++ b/include/cache/Cache.class.php
@@ -26,30 +26,34 @@
 	const Template = 'data.tpl';
 
 	/**
-	 * instance
-	 *
-	 * Stores the singleton instance
+	 * objectCacheInstance
+	 *
+	 * Stores the singleton instance of the object cache
 	 *
 	 * @access protected
 	 * @static
 	 */
-	protected static $instance;
-
-	/**
-	 * GetInstance
-	 *
-	 * Return the singleton instance
+	protected static $objectCacheInstance;
+
+	/**
+	 * GetObjectCacheInstance
+	 *
+	 * Return the singleton instance of the object cache
 	 *
 	 * @access public
 	 * @static
 	 * @return mixed instance of cache class
 	 */
-	public static function GetInstance()
-	{
-		if (!self::$instance) {
-			self::$instance = new GitPHP_Cache();
+	public static function GetObjectCacheInstance()
+	{
+		if (!self::$objectCacheInstance) {
+			self::$objectCacheInstance = new GitPHP_Cache();
+			if (GitPHP_Config::GetInstance()->GetValue('objectcache', false)) {
+				self::$objectCacheInstance->SetEnabled(true);
+				self::$objectCacheInstance->SetLifetime(GitPHP_Config::GetInstance()->GetValue('objectcachelifetime', 86400));
+			}
 		}
-		return self::$instance;
+		return self::$objectCacheInstance;
 	}
 
 	/**
@@ -80,8 +84,6 @@
 	 */
 	public function __construct()
 	{
-		if (GitPHP_Config::GetInstance()->GetValue('objectcache', false))
-			$this->SetEnabled(true);
 	}
 
 	/**
@@ -119,6 +121,38 @@
 	}
 
 	/**
+	 * GetLifetime
+	 *
+	 * Gets the cache lifetime
+	 *
+	 * @access public
+	 * @return int cache lifetime in seconds
+	 */
+	public function GetLifetime()
+	{
+		if (!$this->enabled)
+			return false;
+
+		return $this->tpl->cache_lifetime;
+	}
+
+	/**
+	 * SetLifetime
+	 *
+	 * Sets the cache lifetime
+	 *
+	 * @access public
+	 * @param int $lifetime cache lifetime in seconds
+	 */
+	public function SetLifetime($lifetime)
+	{
+		if (!$this->enabled)
+			return;
+
+		$this->tpl->cache_lifetime = $lifetime;
+	}
+
+	/**
 	 * Get
 	 *
 	 * Get an item from the cache
@@ -151,14 +185,21 @@
 	 * @access public
 	 * @param string $key cache key
 	 * @param mixed $value value
-	 */
-	public function Set($key = null, $value = null)
+	 * @param int $lifetime override the lifetime for this data
+	 */
+	public function Set($key = null, $value = null, $lifetime = null)
 	{
 		if (empty($key) || empty($value))
 			return;
 
 		if (!$this->enabled)
 			return;
+
+		$oldLifetime = null;
+		if ($lifetime !== null) {
+			$oldLifetime = $this->tpl->cache_lifetime;
+			$this->tpl->cache_lifetime = $lifetime;
+		}
 
 		$this->Delete($key);
 		$this->tpl->clear_all_assign();
@@ -167,6 +208,10 @@
 		// Force it into smarty's cache
 		$tmp = $this->tpl->fetch(GitPHP_Cache::Template, $key);
 		unset($tmp);
+
+		if ($lifetime !== null) {
+			$this->tpl->cache_lifetime = $oldLifetime;
+		}
 	}
 
 	/**
@@ -235,11 +280,11 @@
 		if ($this->tpl)
 			return;
 
+		require_once(GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('smarty_prefix', 'lib/smarty/libs/')) . 'Smarty.class.php');
 		$this->tpl = new Smarty;
+		$this->tpl->plugins_dir[] = GITPHP_INCLUDEDIR . 'smartyplugins';
 
 		$this->tpl->caching = 2;
-
-		$this->tpl->cache_lifetime = GitPHP_Config::GetInstance()->GetValue('objectcachelifetime', 86400);
 
 		$servers = GitPHP_Config::GetInstance()->GetValue('memcache', null);
 		if (isset($servers) && is_array($servers) && (count($servers) > 0)) {

--- a/include/git/Blob.class.php
+++ b/include/git/Blob.class.php
@@ -132,7 +132,7 @@
 	{
 		$this->dataRead = true;
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetProject()->GetCompat()) {
 			$exe = new GitPHP_GitExe($this->GetProject());
 
 			$args = array();
@@ -144,7 +144,7 @@
 			$this->data = $this->GetProject()->GetObject($this->hash);
 		}
 
-		GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+		GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 	}
 
 	/**

--- a/include/git/Commit.class.php
+++ b/include/git/Commit.class.php
@@ -541,7 +541,7 @@
 
 		$lines = null;
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetProject()->GetCompat()) {
 
 			/* get data from git_rev_list */
 			$exe = new GitPHP_GitExe($this->GetProject());
@@ -617,7 +617,7 @@
 			}
 		}
 
-		GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+		GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 	}
 
 	/**
@@ -708,7 +708,7 @@
 			}
 		}
 
-		GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+		GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 	}
 
 	/**
@@ -763,13 +763,13 @@
 	{
 		$this->hashPathsRead = true;
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetProject()->GetCompat()) {
 			$this->ReadHashPathsGit();
 		} else {
 			$this->ReadHashPathsRaw($this->GetTree());
 		}
 
-		GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+		GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 	}
 
 	/**

--- a/include/git/Project.class.php
+++ b/include/git/Project.class.php
@@ -25,6 +25,8 @@
 class GitPHP_Project
 {
 
+/* internal variables {{{1*/
+
 	/**
 	 * projectRoot
 	 *
@@ -43,6 +45,8 @@
 	 */
 	protected $project;
 
+/* owner internal variables {{{2*/
+
 	/**
 	 * owner
 	 *
@@ -60,6 +64,10 @@
 	 * @access protected
 	 */
 	protected $ownerRead = false;
+
+/*}}}2*/
+
+/* description internal variables {{{2*/
 
 	/**
 	 * description
@@ -80,6 +88,8 @@
 	 */
 	protected $readDescription = false;
 
+/*}}}2*/
+
 	/**
 	 * category
 	 *
@@ -89,6 +99,8 @@
 	 */
 	protected $category = '';
 
+/* epoch internal variables {{{2*/
+
 	/**
 	 * epoch
 	 *
@@ -107,6 +119,10 @@
 	 */
 	protected $epochRead = false;
 
+/*}}}2*/
+
+/* HEAD internal variables {{{2*/
+
 	/**
 	 * head
 	 *
@@ -125,6 +141,10 @@
 	 */
 	protected $readHeadRef = false;
 
+/*}}}*/
+
+/* ref internal variables {{{2*/
+
 	/**
 	 * tags
 	 *
@@ -152,6 +172,10 @@
 	 */
 	protected $readRefs = false;
 
+/*}}}2*/
+
+/* url internal variables {{{2*/
+
 	/**
 	 * cloneUrl
 	 *
@@ -170,6 +194,10 @@
 	 */
 	protected $pushUrl = null;
 
+/*}}}2*/
+
+/* bugtracker internal variables {{{2*/
+
 	/**
 	 * bugUrl
 	 *
@@ -187,6 +215,8 @@
 	 * @access protected
 	 */
 	protected $bugPattern = null;
+
+/*}}}2*/
 
 	/**
 	 * commitCache
@@ -198,6 +228,8 @@
 	 */
 	protected $commitCache = array();
 
+/* packfile internal variables {{{2*/
+
 	/**
 	 * packs
 	 *
@@ -215,6 +247,22 @@
 	 * @access protected
 	 */
 	protected $packsRead = false;
+
+/*}}}2*/
+
+	/**
+	 * compat
+	 *
+	 * Stores whether this project is running
+	 * in compatibility mode
+	 *
+	 * @access protected
+	 */
+	protected $compat = null;
+
+/*}}}1*/
+
+/* class methods {{{1*/
 
 	/**
 	 * __construct
@@ -232,6 +280,25 @@
 		$this->SetProject($project);
 	}
 
+/*}}}1*/
+
+/* accessors {{{1*/
+
+/* project accessors {{{2*/
+
+	/**
+	 * GetProject
+	 *
+	 * Gets the project
+	 *
+	 * @access public
+	 * @return string the project
+	 */
+	public function GetProject()
+	{
+		return $this->project;
+	}
+
 	/**
 	 * SetProject
 	 *
@@ -268,6 +335,41 @@
 
 	}
 
+/*}}}2*/
+
+	/**
+	 * GetSlug
+	 *
+	 * Gets the project as a filename/url friendly slug
+	 *
+	 * @access public
+	 * @return string the slug
+	 */
+	public function GetSlug()
+	{
+		$project = $this->project;
+
+		if (substr($project, -4) == '.git')
+			$project = substr($project, 0, -4);
+		
+		return GitPHP_Util::MakeSlug($project);
+	}
+
+	/**
+	 * GetPath
+	 *
+	 * Gets the full project path
+	 *
+	 * @access public
+	 * @return string project path
+	 */
+	public function GetPath()
+	{
+		return $this->projectRoot . $this->project;
+	}
+
+/* owner accessors {{{2 */
+
 	/**
 	 * GetOwner
 	 *
@@ -294,7 +396,7 @@
 	 */
 	protected function ReadOwner()
 	{
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetCompat()) {
 			$this->ReadOwnerGit();
 		} else {
 			$this->ReadOwnerRaw();
@@ -385,18 +487,9 @@
 		$this->owner = $owner;
 	}
 
-	/**
-	 * GetProject
-	 *
-	 * Gets the project
-	 *
-	 * @access public
-	 * @return string the project
-	 */
-	public function GetProject()
-	{
-		return $this->project;
-	}
+/*}}}2*/
+
+/* projectroot accessors {{{2*/
 
 	/**
 	 * GetProjectRoot
@@ -411,36 +504,9 @@
 		return $this->projectRoot;
 	}
 
-	/**
-	 * GetSlug
-	 *
-	 * Gets the project as a filename/url friendly slug
-	 *
-	 * @access public
-	 * @return string the slug
-	 */
-	public function GetSlug()
-	{
-		$project = $this->project;
-
-		if (substr($project, -4) == '.git')
-			$project = substr($project, 0, -4);
-		
-		return GitPHP_Util::MakeSlug($project);
-	}
-
-	/**
-	 * GetPath
-	 *
-	 * Gets the full project path
-	 *
-	 * @access public
-	 * @return string project path
-	 */
-	public function GetPath()
-	{
-		return $this->projectRoot . $this->project;
-	}
+/*}}}2*/
+
+/* description accessors {{{2*/
 
 	/**
 	 * GetDescription
@@ -481,6 +547,8 @@
 		$this->readDescription = true;
 	}
 
+/*}}}2*/
+
 	/**
 	 * GetDaemonEnabled
 	 *
@@ -493,6 +561,8 @@
 	{
 		return file_exists($this->GetPath() . '/git-daemon-export-ok');
 	}
+
+/* category accessors {{{2*/
 
 	/**
 	 * GetCategory
@@ -520,6 +590,10 @@
 		$this->category = $category;
 	}
 
+/*}}}2*/
+
+/* clone url accessors {{{2*/
+
 	/**
 	 * GetCloneUrl
 	 *
@@ -553,6 +627,10 @@
 		$this->cloneUrl = $cUrl;
 	}
 
+/*}}}2*/
+
+/* push url accessors {{{2*/
+
 	/**
 	 * GetPushUrl
 	 *
@@ -586,6 +664,10 @@
 		$this->pushUrl = $pUrl;
 	}
 
+/*}}}2*/
+
+/* bugtracker accessors {{{2*/
+
 	/**
 	 * GetBugUrl
 	 *
@@ -644,6 +726,10 @@
 		$this->bugPattern = $bPat;
 	}
 
+/*}}}2*/
+
+/* HEAD accessors {{{2*/
+
 	/**
 	 * GetHeadCommit
 	 *
@@ -672,7 +758,7 @@
 	{
 		$this->readHeadRef = true;
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetCompat()) {
 			$this->ReadHeadCommitGit();
 		} else {
 			$this->ReadHeadCommitRaw();
@@ -718,6 +804,157 @@
 			}
 		}
 	}
+
+/*}}}2*/
+
+/* epoch accessors {{{2*/
+
+	/**
+	 * GetEpoch
+	 *
+	 * Gets this project's epoch
+	 * (time of last change)
+	 *
+	 * @access public
+	 * @return integer timestamp
+	 */
+	public function GetEpoch()
+	{
+		if (!$this->epochRead)
+			$this->ReadEpoch();
+
+		return $this->epoch;
+	}
+
+	/**
+	 * GetAge
+	 *
+	 * Gets this project's age
+	 * (time since most recent change)
+	 *
+	 * @access public
+	 * @return integer age
+	 */
+	public function GetAge()
+	{
+		if (!$this->epochRead)
+			$this->ReadEpoch();
+
+		return time() - $this->epoch;
+	}
+
+	/**
+	 * ReadEpoch
+	 *
+	 * Reads this project's epoch
+	 * (timestamp of most recent change)
+	 *
+	 * @access private
+	 */
+	private function ReadEpoch()
+	{
+		$this->epochRead = true;
+
+		if ($this->GetCompat()) {
+			$this->ReadEpochGit();
+		} else {
+			$this->ReadEpochRaw();
+		}
+	}
+
+	/**
+	 * ReadEpochGit
+	 *
+	 * Reads this project's epoch using git executable
+	 *
+	 * @access private
+	 */
+	private function ReadEpochGit()
+	{
+		$exe = new GitPHP_GitExe($this);
+
+		$args = array();
+		$args[] = '--format="%(committer)"';
+		$args[] = '--sort=-committerdate';
+		$args[] = '--count=1';
+		$args[] = 'refs/heads';
+
+		$epochstr = trim($exe->Execute(GIT_FOR_EACH_REF, $args));
+
+		if (preg_match('/ (\d+) [-+][01]\d\d\d$/', $epochstr, $regs)) {
+			$this->epoch = $regs[1];
+		}
+
+		unset($exe);
+	}
+
+	/**
+	 * ReadEpochRaw
+	 *
+	 * Reads this project's epoch using raw objects
+	 *
+	 * @access private
+	 */
+	private function ReadEpochRaw()
+	{
+		if (!$this->readRefs)
+			$this->ReadRefList();
+
+		$epoch = 0;
+		foreach ($this->heads as $head) {
+			$commit = $head->GetCommit();
+			if ($commit) {
+				if ($commit->GetCommitterEpoch() > $epoch) {
+					$epoch = $commit->GetCommitterEpoch();
+				}
+			}
+		}
+		if ($epoch > 0) {
+			$this->epoch = $epoch;
+		}
+	}
+
+/*}}}2*/
+
+/* compatibility accessors {{{2*/
+
+	/**
+	 * GetCompat
+	 *
+	 * Gets whether this project is running in compatibility mode
+	 *
+	 * @access public
+	 * @return boolean true if compatibilty mode
+	 */
+	public function GetCompat()
+	{
+		if ($this->compat !== null) {
+			return $this->compat;
+		}
+
+		return GitPHP_Config::GetInstance()->GetValue('compat', false);
+	}
+
+	/**
+	 * SetCompat
+	 *
+	 * Sets whether this project is running in compatibility mode
+	 *
+	 * @access public
+	 * @param boolean true if compatibility mode
+	 */
+	public function SetCompat($compat)
+	{
+		$this->compat = $compat;
+	}
+
+/*}}}2*/
+
+/*}}}1*/
+
+/* data loading methods {{{1*/
+
+/* commit loading methods {{{2*/
 
 	/**
 	 * GetCommit
@@ -754,7 +991,7 @@
 
 			if (!isset($this->commitCache[$hash])) {
 				$cacheKey = 'project|' . $this->project . '|commit|' . $hash;
-				$cached = GitPHP_Cache::GetInstance()->Get($cacheKey);
+				$cached = GitPHP_Cache::GetObjectCacheInstance()->Get($cacheKey);
 				if ($cached)
 					$this->commitCache[$hash] = $cached;
 				else
@@ -777,87 +1014,9 @@
 		return null;
 	}
 
-	/**
-	 * CompareProject
-	 *
-	 * Compares two projects by project name
-	 *
-	 * @access public
-	 * @static
-	 * @param mixed $a first project
-	 * @param mixed $b second project
-	 * @return integer comparison result
-	 */
-	public static function CompareProject($a, $b)
-	{
-		$catCmp = strcmp($a->GetCategory(), $b->GetCategory());
-		if ($catCmp !== 0)
-			return $catCmp;
-
-		return strcmp($a->GetProject(), $b->GetProject());
-	}
-
-	/**
-	 * CompareDescription
-	 *
-	 * Compares two projects by description
-	 *
-	 * @access public
-	 * @static
-	 * @param mixed $a first project
-	 * @param mixed $b second project
-	 * @return integer comparison result
-	 */
-	public static function CompareDescription($a, $b)
-	{
-		$catCmp = strcmp($a->GetCategory(), $b->GetCategory());
-		if ($catCmp !== 0)
-			return $catCmp;
-
-		return strcmp($a->GetDescription(), $b->GetDescription());
-	}
-
-	/**
-	 * CompareOwner
-	 *
-	 * Compares two projects by owner
-	 *
-	 * @access public
-	 * @static
-	 * @param mixed $a first project
-	 * @param mixed $b second project
-	 * @return integer comparison result
-	 */
-	public static function CompareOwner($a, $b)
-	{
-		$catCmp = strcmp($a->GetCategory(), $b->GetCategory());
-		if ($catCmp !== 0)
-			return $catCmp;
-
-		return strcmp($a->GetOwner(), $b->GetOwner());
-	}
-
-	/**
-	 * CompareAge
-	 *
-	 * Compares two projects by age
-	 *
-	 * @access public
-	 * @static
-	 * @param mixed $a first project
-	 * @param mixed $b second project
-	 * @return integer comparison result
-	 */
-	public static function CompareAge($a, $b)
-	{
-		$catCmp = strcmp($a->GetCategory(), $b->GetCategory());
-		if ($catCmp !== 0)
-			return $catCmp;
-
-		if ($a->GetAge() === $b->GetAge())
-			return 0;
-		return ($a->GetAge() < $b->GetAge() ? -1 : 1);
-	}
+/*}}}2*/
+
+/* ref loading methods {{{2*/
 
 	/**
 	 * GetRefs
@@ -893,7 +1052,7 @@
 	{
 		$this->readRefs = true;
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetCompat()) {
 			$this->ReadRefListGit();
 		} else {
 			$this->ReadRefListRaw();
@@ -1053,6 +1212,10 @@
 		return $files;
 	}
 
+/*}}}2*/
+
+/* tag loading methods {{{2*/
+
 	/**
 	 * GetTags
 	 *
@@ -1067,7 +1230,7 @@
 		if (!$this->readRefs)
 			$this->ReadRefList();
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetCompat()) {
 			return $this->GetTagsGit($count);
 		} else {
 			return $this->GetTagsRaw($count);
@@ -1172,7 +1335,7 @@
 			return;
 
 		$cacheKey = 'project|' . $this->project . '|tag|' . $tag;
-		$cached = GitPHP_Cache::GetInstance()->Get($cacheKey);
+		$cached = GitPHP_Cache::GetObjectCacheInstance()->Get($cacheKey);
 		if ($cached) {
 			return $cached;
 		} else {
@@ -1180,6 +1343,10 @@
 		}
 	}
 
+/*}}}2*/
+
+/* head loading methods {{{2*/
+
 	/**
 	 * GetHeads
 	 *
@@ -1194,7 +1361,7 @@
 		if (!$this->readRefs)
 			$this->ReadRefList();
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetCompat()) {
 			return $this->GetHeadsGit($count);
 		} else {
 			return $this->GetHeadsRaw($count);
@@ -1283,6 +1450,10 @@
 		return $this->heads[$key];
 	}
 
+/*}}}2*/
+
+/* log methods {{{2*/
+
 	/**
 	 * GetLogHash
 	 *
@@ -1312,7 +1483,7 @@
 	 */
 	public function GetLog($hash, $count = 50, $skip = 0)
 	{
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false) || ($skip > GitPHP_Config::GetInstance()->GetValue('largeskip', 200)) ) {
+		if ($this->GetCompat() || ($skip > GitPHP_Config::GetInstance()->GetValue('largeskip', 200)) ) {
 			return $this->GetLogGit($hash, $count, $skip);
 		} else {
 			return $this->GetLogRaw($hash, $count, $skip);
@@ -1396,6 +1567,10 @@
 		return $log;
 	}
 
+/*}}}2*/
+
+/* blob loading methods {{{2*/
+
 	/**
 	 * GetBlob
 	 *
@@ -1410,13 +1585,17 @@
 			return null;
 
 		$cacheKey = 'project|' . $this->project . '|blob|' . $hash;
-		$cached = GitPHP_Cache::GetInstance()->Get($cacheKey);
+		$cached = GitPHP_Cache::GetObjectCacheInstance()->Get($cacheKey);
 		if ($cached)
 			return $cached;
 
 		return new GitPHP_Blob($this, $hash);
 	}
 
+/*}}}2*/
+
+/* tree loading methods {{{2*/
+
 	/**
 	 * GetTree
 	 *
@@ -1431,271 +1610,16 @@
 			return null;
 
 		$cacheKey = 'project|' . $this->project . '|tree|' . $hash;
-		$cached = GitPHP_Cache::GetInstance()->Get($cacheKey);
+		$cached = GitPHP_Cache::GetObjectCacheInstance()->Get($cacheKey);
 		if ($cached)
 			return $cached;
 
 		return new GitPHP_Tree($this, $hash);
 	}
 
-	/**
-	 * SearchCommit
-	 *
-	 * Gets a list of commits with commit messages matching the given pattern
-	 *
-	 * @access public
-	 * @param string $pattern search pattern
-	 * @param string $hash hash to start searching from
-	 * @param integer $count number of results to get
-	 * @param integer $skip number of results to skip
-	 * @return array array of matching commits
-	 */
-	public function SearchCommit($pattern, $hash = 'HEAD', $count = 50, $skip = 0)
-	{
-		if (empty($pattern))
-			return;
-
-		$args = array();
-
-		$exe = new GitPHP_GitExe($this);
-		if ($exe->CanIgnoreRegexpCase())
-			$args[] = '--regexp-ignore-case';
-		unset($exe);
-
-		$args[] = '--grep=\'' . $pattern . '\'';
-
-		$ret = $this->RevList($hash, $count, $skip, $args);
-		$len = count($ret);
-
-		for ($i = 0; $i < $len; ++$i) {
-			$ret[$i] = $this->GetCommit($ret[$i]);
-		}
-		return $ret;
-	}
-
-	/**
-	 * SearchAuthor
-	 *
-	 * Gets a list of commits with authors matching the given pattern
-	 *
-	 * @access public
-	 * @param string $pattern search pattern
-	 * @param string $hash hash to start searching from
-	 * @param integer $count number of results to get
-	 * @param integer $skip number of results to skip
-	 * @return array array of matching commits
-	 */
-	public function SearchAuthor($pattern, $hash = 'HEAD', $count = 50, $skip = 0)
-	{
-		if (empty($pattern))
-			return;
-
-		$args = array();
-
-		$exe = new GitPHP_GitExe($this);
-		if ($exe->CanIgnoreRegexpCase())
-			$args[] = '--regexp-ignore-case';
-		unset($exe);
-
-		$args[] = '--author=\'' . $pattern . '\'';
-
-		$ret = $this->RevList($hash, $count, $skip, $args);
-		$len = count($ret);
-
-		for ($i = 0; $i < $len; ++$i) {
-			$ret[$i] = $this->GetCommit($ret[$i]);
-		}
-		return $ret;
-	}
-
-	/**
-	 * SearchCommitter
-	 *
-	 * Gets a list of commits with committers matching the given pattern
-	 *
-	 * @access public
-	 * @param string $pattern search pattern
-	 * @param string $hash hash to start searching from
-	 * @param integer $count number of results to get
-	 * @param integer $skip number of results to skip
-	 * @return array array of matching commits
-	 */
-	public function SearchCommitter($pattern, $hash = 'HEAD', $count = 50, $skip = 0)
-	{
-		if (empty($pattern))
-			return;
-
-		$args = array();
-
-		$exe = new GitPHP_GitExe($this);
-		if ($exe->CanIgnoreRegexpCase())
-			$args[] = '--regexp-ignore-case';
-		unset($exe);
-
-		$args[] = '--committer=\'' . $pattern . '\'';
-
-		$ret = $this->RevList($hash, $count, $skip, $args);
-		$len = count($ret);
-
-		for ($i = 0; $i < $len; ++$i) {
-			$ret[$i] = $this->GetCommit($ret[$i]);
-		}
-		return $ret;
-	}
-
-	/**
-	 * RevList
-	 *
-	 * Common code for using rev-list command
-	 *
-	 * @access private
-	 * @param string $hash hash to list from
-	 * @param integer $count number of results to get
-	 * @param integer $skip number of results to skip
-	 * @param array $args args to give to rev-list
-	 * @return array array of hashes
-	 */
-	private function RevList($hash, $count = 50, $skip = 0, $args = array())
-	{
-		if ($count < 1)
-			return;
-
-		$exe = new GitPHP_GitExe($this);
-
-		$canSkip = true;
-		
-		if ($skip > 0)
-			$canSkip = $exe->CanSkip();
-
-		if ($canSkip) {
-			$args[] = '--max-count=' . $count;
-			if ($skip > 0) {
-				$args[] = '--skip=' . $skip;
-			}
-		} else {
-			$args[] = '--max-count=' . ($count + $skip);
-		}
-
-		$args[] = $hash;
-
-		$revlist = explode("\n", $exe->Execute(GIT_REV_LIST, $args));
-
-		if (!$revlist[count($revlist)-1]) {
-			/* the last newline creates a null entry */
-			array_splice($revlist, -1, 1);
-		}
-
-		if (($skip > 0) && (!$exe->CanSkip())) {
-			return array_slice($revlist, $skip, $count);
-		}
-
-		return $revlist;
-	}
-
-	/**
-	 * GetEpoch
-	 *
-	 * Gets this project's epoch
-	 * (time of last change)
-	 *
-	 * @access public
-	 * @return integer timestamp
-	 */
-	public function GetEpoch()
-	{
-		if (!$this->epochRead)
-			$this->ReadEpoch();
-
-		return $this->epoch;
-	}
-
-	/**
-	 * GetAge
-	 *
-	 * Gets this project's age
-	 * (time since most recent change)
-	 *
-	 * @access public
-	 * @return integer age
-	 */
-	public function GetAge()
-	{
-		if (!$this->epochRead)
-			$this->ReadEpoch();
-
-		return time() - $this->epoch;
-	}
-
-	/**
-	 * ReadEpoch
-	 *
-	 * Reads this project's epoch
-	 * (timestamp of most recent change)
-	 *
-	 * @access private
-	 */
-	private function ReadEpoch()
-	{
-		$this->epochRead = true;
-
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
-			$this->ReadEpochGit();
-		} else {
-			$this->ReadEpochRaw();
-		}
-	}
-
-	/**
-	 * ReadEpochGit
-	 *
-	 * Reads this project's epoch using git executable
-	 *
-	 * @access private
-	 */
-	private function ReadEpochGit()
-	{
-		$exe = new GitPHP_GitExe($this);
-
-		$args = array();
-		$args[] = '--format="%(committer)"';
-		$args[] = '--sort=-committerdate';
-		$args[] = '--count=1';
-		$args[] = 'refs/heads';
-
-		$epochstr = trim($exe->Execute(GIT_FOR_EACH_REF, $args));
-
-		if (preg_match('/ (\d+) [-+][01]\d\d\d$/', $epochstr, $regs)) {
-			$this->epoch = $regs[1];
-		}
-
-		unset($exe);
-	}
-
-	/**
-	 * ReadEpochRaw
-	 *
-	 * Reads this project's epoch using raw objects
-	 *
-	 * @access private
-	 */
-	private function ReadEpochRaw()
-	{
-		if (!$this->readRefs)
-			$this->ReadRefList();
-
-		$epoch = 0;
-		foreach ($this->heads as $head) {
-			$commit = $head->GetCommit();
-			if ($commit) {
-				if ($commit->GetCommitterEpoch() > $epoch) {
-					$epoch = $commit->GetCommitterEpoch();
-				}
-			}
-		}
-		if ($epoch > 0) {
-			$this->epoch = $epoch;
-		}
-	}
+/*}}}2*/
+
+/* raw object loading methods {{{2*/
 
 	/**
 	 * GetObject
@@ -1769,5 +1693,257 @@
 		$this->packsRead = true;
 	}
 
+/*}}}2*/
+
+/*}}}1*/
+
+/* search methods {{{1*/
+
+	/**
+	 * SearchCommit
+	 *
+	 * Gets a list of commits with commit messages matching the given pattern
+	 *
+	 * @access public
+	 * @param string $pattern search pattern
+	 * @param string $hash hash to start searching from
+	 * @param integer $count number of results to get
+	 * @param integer $skip number of results to skip
+	 * @return array array of matching commits
+	 */
+	public function SearchCommit($pattern, $hash = 'HEAD', $count = 50, $skip = 0)
+	{
+		if (empty($pattern))
+			return;
+
+		$args = array();
+
+		$exe = new GitPHP_GitExe($this);
+		if ($exe->CanIgnoreRegexpCase())
+			$args[] = '--regexp-ignore-case';
+		unset($exe);
+
+		$args[] = '--grep=\'' . $pattern . '\'';
+
+		$ret = $this->RevList($hash, $count, $skip, $args);
+		$len = count($ret);
+
+		for ($i = 0; $i < $len; ++$i) {
+			$ret[$i] = $this->GetCommit($ret[$i]);
+		}
+		return $ret;
+	}
+
+	/**
+	 * SearchAuthor
+	 *
+	 * Gets a list of commits with authors matching the given pattern
+	 *
+	 * @access public
+	 * @param string $pattern search pattern
+	 * @param string $hash hash to start searching from
+	 * @param integer $count number of results to get
+	 * @param integer $skip number of results to skip
+	 * @return array array of matching commits
+	 */
+	public function SearchAuthor($pattern, $hash = 'HEAD', $count = 50, $skip = 0)
+	{
+		if (empty($pattern))
+			return;
+
+		$args = array();
+
+		$exe = new GitPHP_GitExe($this);
+		if ($exe->CanIgnoreRegexpCase())
+			$args[] = '--regexp-ignore-case';
+		unset($exe);
+
+		$args[] = '--author=\'' . $pattern . '\'';
+
+		$ret = $this->RevList($hash, $count, $skip, $args);
+		$len = count($ret);
+
+		for ($i = 0; $i < $len; ++$i) {
+			$ret[$i] = $this->GetCommit($ret[$i]);
+		}
+		return $ret;
+	}
+
+	/**
+	 * SearchCommitter
+	 *
+	 * Gets a list of commits with committers matching the given pattern
+	 *
+	 * @access public
+	 * @param string $pattern search pattern
+	 * @param string $hash hash to start searching from
+	 * @param integer $count number of results to get
+	 * @param integer $skip number of results to skip
+	 * @return array array of matching commits
+	 */
+	public function SearchCommitter($pattern, $hash = 'HEAD', $count = 50, $skip = 0)
+	{
+		if (empty($pattern))
+			return;
+
+		$args = array();
+
+		$exe = new GitPHP_GitExe($this);
+		if ($exe->CanIgnoreRegexpCase())
+			$args[] = '--regexp-ignore-case';
+		unset($exe);
+
+		$args[] = '--committer=\'' . $pattern . '\'';
+
+		$ret = $this->RevList($hash, $count, $skip, $args);
+		$len = count($ret);
+
+		for ($i = 0; $i < $len; ++$i) {
+			$ret[$i] = $this->GetCommit($ret[$i]);
+		}
+		return $ret;
+	}
+
+/*}}}1*/
+
+/* private utilities {{{1*/
+
+	/**
+	 * RevList
+	 *
+	 * Common code for using rev-list command
+	 *
+	 * @access private
+	 * @param string $hash hash to list from
+	 * @param integer $count number of results to get
+	 * @param integer $skip number of results to skip
+	 * @param array $args args to give to rev-list
+	 * @return array array of hashes
+	 */
+	private function RevList($hash, $count = 50, $skip = 0, $args = array())
+	{
+		if ($count < 1)
+			return;
+
+		$exe = new GitPHP_GitExe($this);
+
+		$canSkip = true;
+		
+		if ($skip > 0)
+			$canSkip = $exe->CanSkip();
+
+		if ($canSkip) {
+			$args[] = '--max-count=' . $count;
+			if ($skip > 0) {
+				$args[] = '--skip=' . $skip;
+			}
+		} else {
+			$args[] = '--max-count=' . ($count + $skip);
+		}
+
+		$args[] = $hash;
+
+		$revlist = explode("\n", $exe->Execute(GIT_REV_LIST, $args));
+
+		if (!$revlist[count($revlist)-1]) {
+			/* the last newline creates a null entry */
+			array_splice($revlist, -1, 1);
+		}
+
+		if (($skip > 0) && (!$exe->CanSkip())) {
+			return array_slice($revlist, $skip, $count);
+		}
+
+		return $revlist;
+	}
+
+/*}}}1*/
+
+/* static utilities {{{1*/
+
+	/**
+	 * CompareProject
+	 *
+	 * Compares two projects by project name
+	 *
+	 * @access public
+	 * @static
+	 * @param mixed $a first project
+	 * @param mixed $b second project
+	 * @return integer comparison result
+	 */
+	public static function CompareProject($a, $b)
+	{
+		$catCmp = strcmp($a->GetCategory(), $b->GetCategory());
+		if ($catCmp !== 0)
+			return $catCmp;
+
+		return strcmp($a->GetProject(), $b->GetProject());
+	}
+
+	/**
+	 * CompareDescription
+	 *
+	 * Compares two projects by description
+	 *
+	 * @access public
+	 * @static
+	 * @param mixed $a first project
+	 * @param mixed $b second project
+	 * @return integer comparison result
+	 */
+	public static function CompareDescription($a, $b)
+	{
+		$catCmp = strcmp($a->GetCategory(), $b->GetCategory());
+		if ($catCmp !== 0)
+			return $catCmp;
+
+		return strcmp($a->GetDescription(), $b->GetDescription());
+	}
+
+	/**
+	 * CompareOwner
+	 *
+	 * Compares two projects by owner
+	 *
+	 * @access public
+	 * @static
+	 * @param mixed $a first project
+	 * @param mixed $b second project
+	 * @return integer comparison result
+	 */
+	public static function CompareOwner($a, $b)
+	{
+		$catCmp = strcmp($a->GetCategory(), $b->GetCategory());
+		if ($catCmp !== 0)
+			return $catCmp;
+
+		return strcmp($a->GetOwner(), $b->GetOwner());
+	}
+
+	/**
+	 * CompareAge
+	 *
+	 * Compares two projects by age
+	 *
+	 * @access public
+	 * @static
+	 * @param mixed $a first project
+	 * @param mixed $b second project
+	 * @return integer comparison result
+	 */
+	public static function CompareAge($a, $b)
+	{
+		$catCmp = strcmp($a->GetCategory(), $b->GetCategory());
+		if ($catCmp !== 0)
+			return $catCmp;
+
+		if ($a->GetAge() === $b->GetAge())
+			return 0;
+		return ($a->GetAge() < $b->GetAge() ? -1 : 1);
+	}
+
+/*}}}1*/
+
 }
 

--- a/include/git/ProjectList.class.php
+++ b/include/git/ProjectList.class.php
@@ -66,6 +66,7 @@
 		if (self::$instance)
 			return;
 
+
 		if (!empty($file) && is_file($file) && include($file)) {
 			if (isset($git_projects)) {
 				if (is_string($git_projects)) {
@@ -84,8 +85,10 @@
 			}
 		}
 
-		if (!self::$instance)
+		if (!self::$instance) {
+
 			self::$instance = new GitPHP_ProjectListDirectory(GitPHP_Config::GetInstance()->GetValue('projectroot'));
+		}
 
 		if (isset($git_projects_settings) && !$legacy)
 			self::$instance->ApplySettings($git_projects_settings);

--- a/include/git/ProjectListArray.class.php
+++ b/include/git/ProjectListArray.class.php
@@ -74,6 +74,7 @@
 					}
 				}
 			} catch (Exception $e) {
+				GitPHP_Log::GetInstance()->Log($e->getMessage());
 			}
 		}
 	}

--- a/include/git/ProjectListArrayLegacy.class.php
+++ b/include/git/ProjectListArrayLegacy.class.php
@@ -66,6 +66,7 @@
 							$projObj->SetCategory($cat);
 						$this->projects[$ppath] = $projObj;
 					} catch (Exception $e) {
+						GitPHP_Log::GetInstance()->Log($e->getMessage());
 					}
 				}
 			}

--- a/include/git/ProjectListBase.class.php
+++ b/include/git/ProjectListBase.class.php
@@ -295,6 +295,9 @@
 		if (isset($projData['bugurl']) && is_string($projData['bugurl'])) {
 			$projectObj->SetBugUrl($projData['bugurl']);
 		}
+		if (isset($projData['compat'])) {
+			$projectObj->SetCompat($projData['compat']);
+		}
 	}
 
 	/**

--- a/include/git/ProjectListDirectory.class.php
+++ b/include/git/ProjectListDirectory.class.php
@@ -61,7 +61,17 @@
 	 */
 	protected function PopulateProjects()
 	{
+		$key = 'projectdir|' . $this->projectDir . '|projectlist|directory';
+		$cached = GitPHP_Cache::GetObjectCacheInstance()->Get($key);
+		if ($cached && (count($cached) > 0)) {
+			GitPHP_Log::GetInstance()->Log('Loaded ' . count($cached) . ' projects from cache');
+			$this->projects = $cached;
+			return;
+		}
+
 		$this->RecurseDir($this->projectDir);
+
+		GitPHP_Cache::GetObjectCacheInstance()->Set($key, $this->projects, GitPHP_Config::GetInstance()->GetValue('cachelifetime', 3600));
 	}
 
 	/**
@@ -76,12 +86,15 @@
 		if (!is_dir($dir))
 			return;
 
+		GitPHP_Log::GetInstance()->Log(sprintf('Searching directory %1$s', $dir));
+
 		if ($dh = opendir($dir)) {
 			$trimlen = strlen($this->projectDir) + 1;
 			while (($file = readdir($dh)) !== false) {
 				$fullPath = $dir . '/' . $file;
 				if ((strpos($file, '.') !== 0) && is_dir($fullPath)) {
 					if (is_file($fullPath . '/HEAD')) {
+						GitPHP_Log::GetInstance()->Log(sprintf('Found project %1$s', $fullPath));
 						$projectPath = substr($fullPath, $trimlen);
 						try {
 							$proj = new GitPHP_Project($this->projectDir, $projectPath);
@@ -90,10 +103,13 @@
 								$this->projects[$projectPath] = $proj;
 							}
 						} catch (Exception $e) {
+							GitPHP_Log::GetInstance()->Log($e->getMessage());
 						}
 					} else {
 						$this->RecurseDir($fullPath);
 					}
+				} else {
+					GitPHP_Log::GetInstance()->Log(sprintf('Skipping %1$s', $fullPath));
 				}
 			}
 			closedir($dh);

--- a/include/git/ProjectListFile.class.php
+++ b/include/git/ProjectListFile.class.php
@@ -72,7 +72,10 @@
 						}
 						$this->projects[$regs[1]] = $projObj;
 					} catch (Exception $e) {
+						GitPHP_Log::GetInstance()->Log($e->getMessage());
 					}
+				} else {
+					GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $projectRoot . $regs[1]));
 				}
 			}
 		}

--- a/include/git/ProjectListScmManager.class.php
+++ b/include/git/ProjectListScmManager.class.php
@@ -67,10 +67,15 @@
 
 		foreach ($xml->repositories->repository as $repository) {
 
-			if ($repository->type != 'git')
+			if ($repository->type != 'git') {
+				GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $repository->name));
 				continue;
-			if ($repository->public != 'true')
+			}
+
+			if ($repository->public != 'true') {
+				GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not public', $repository->name));
 				continue;
+			}
 
 			$projName = trim($repository->name);
 			if (empty($projName))
@@ -89,7 +94,10 @@
 					}
 					$this->projects[$projName] = $projObj;
 				} catch (Exception $e) {
+					GitPHP_Log::GetInstance()->Log($e->getMessage());
 				}
+			} else {
+				GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $projName));
 			}
 		}
 	}

--- a/include/git/Tag.class.php
+++ b/include/git/Tag.class.php
@@ -330,13 +330,13 @@
 	{
 		$this->dataRead = true;
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetProject()->GetCompat()) {
 			$this->ReadDataGit();
 		} else {
 			$this->ReadDataRaw();
 		}
 
-		GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+		GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 	}
 
 	/**
@@ -359,7 +359,7 @@
 			$this->object = $this->GetProject()->GetCommit($this->GetHash());
 			$this->commit = $this->object;
 			$this->type = 'commit';
-			GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+			GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 			return;
 		}
 
@@ -450,7 +450,7 @@
 			$this->object = $this->GetProject()->GetCommit($this->GetHash());
 			$this->commit = $this->object;
 			$this->type = 'commit';
-			GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+			GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 			return;
 		}
 
@@ -538,7 +538,7 @@
 			}
 		}
 
-		GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+		GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 	}
 
 	/**

--- a/include/git/Tree.class.php
+++ b/include/git/Tree.class.php
@@ -114,13 +114,13 @@
 	{
 		$this->contentsRead = true;
 
-		if (GitPHP_Config::GetInstance()->GetValue('compat', false)) {
+		if ($this->GetProject()->GetCompat()) {
 			$this->ReadContentsGit();
 		} else {
 			$this->ReadContentsRaw();
 		}
 
-		GitPHP_Cache::GetInstance()->Set($this->GetCacheKey(), $this);
+		GitPHP_Cache::GetObjectCacheInstance()->Set($this->GetCacheKey(), $this);
 	}
 
 	/**

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -25,6 +25,8 @@
 define('GITPHP_CONTROLLERDIR', GITPHP_INCLUDEDIR . 'controller/');
 define('GITPHP_CACHEDIR', GITPHP_INCLUDEDIR . 'cache/');
 define('GITPHP_LOCALEDIR', GITPHP_BASEDIR . 'locale/');
+
+define('GITPHP_CACHE', GITPHP_BASEDIR . 'cache/');
 
 include_once(GITPHP_INCLUDEDIR . 'version.php');
 
@@ -184,7 +186,7 @@
 if (GitPHP_Log::GetInstance()->GetEnabled()) {
 	$entries = GitPHP_Log::GetInstance()->GetEntries();
 	foreach ($entries as $logline) {
-		echo "\n" . $logline;
+		echo "<br />\n" . $logline;
 	}
 }
 

comments