Avoid duplication of refs and packed refs
Avoid duplication of refs and packed refs

--- /dev/null
+++ b/include/gitutil.git_read_packed_refs.php
@@ -1,1 +1,38 @@
+<?php
+/*
+ *  gitutil.git_read_packed_refs.php
+ *  gitphp: a PHP git repository browser
+ *  Component: Git utility - read packed refs
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+ require_once('gitutil.git_read_hash.php');
+
+function git_read_packed_refs($projectroot, $project, $refdir)
+{
+	if (!is_file($projectroot . $project . '/packed-refs'))
+		return null;
+
+	$refs = array();
+        $refs = explode("\n",git_read_hash($projectroot . $project . "/" . 'packed-refs'));
+	$reflist = array();
+
+	$dirlen = strlen($refdir);
+
+	foreach ($refs as $i) {
+		if (preg_match('/^([0-9a-f]{40}) (.+)$/i', trim($i), $regs)) {
+			if (strncmp($refdir, $regs[2], $dirlen) === 0) {
+				$regs[2] = substr($regs[2], $dirlen+1);
+				$refobj = git_read_ref($projectroot, $project, $regs[1], $regs[2]);
+				if (isset($refobj))
+					$reflist[] = $refobj;
+			}
+		}
+        }
+
+	return $reflist;
+}
+
+?>
+

--- /dev/null
+++ b/include/gitutil.git_read_ref.php
@@ -1,1 +1,60 @@
+<?php
+/*
+ *  gitutil.git_read_ref.php
+ *  gitphp: A PHP git repository browser
+ *  Component: Git utility - read single ref
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+ require_once('util.age_string.php');
+ require_once('gitutil.git_get_type.php');
+ require_once('gitutil.git_read_tag.php');
+ require_once('gitutil.git_read_commit.php');
+
+ function git_read_ref($projectroot, $project, $ref_id, $ref_file)
+ {
+	$type = git_get_type($projectroot . $project, $ref_id);
+
+	if (!$type)
+		return null;
+
+	$ref_item = array();
+	$ref_item['type'] = $type;
+	$ref_item['id'] = $ref_id;
+	$ref_item['epoch'] = 0;
+	$ref_item['age_string'] = "unknown";
+
+	if ($type == "tag") {
+		$tag = git_read_tag($projectroot . $project, $ref_id);
+		$ref_item['comment'] = $tag['comment'];
+		if ($tag['type'] == "commit") {
+			$co = git_read_commit($projectroot . $project, $tag['object']);
+			$ref_item['epoch'] = $co['committer_epoch'];
+			$ref_item['age_string'] = $co['age_string'];
+			$ref_item['age'] = $co['age'];
+		} else if (isset($tag['epoch'])) {
+			$age = time() - $tag['epoch'];
+			$ref_item['epoch'] = $tag['epoch'];
+			$ref_item['age_string'] = age_string($age);
+			$ref_item['age'] = $age;
+		}
+		$ref_item['reftype'] = $tag['type'];
+		$ref_item['name'] = $tag['name'];
+		$ref_item['refid'] = $tag['object'];
+	} else if ($type == "commit") {
+		$co = git_read_commit($projectroot . $project, $ref_id);
+		$ref_item['reftype'] = "commit";
+		$ref_item['name'] = $ref_file;
+		$ref_item['title'] = $co['title'];
+		$ref_item['refid'] = $ref_id;
+		$ref_item['epoch'] = $co['committer_epoch'];
+		$ref_item['age_string'] = $co['age_string'];
+		$ref_item['age'] = $co['age'];
+	}
+
+	return $ref_item;
+ }
+
+?>
+

--- a/include/gitutil.git_read_refs.php
+++ b/include/gitutil.git_read_refs.php
@@ -7,12 +7,10 @@
  *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
  */
 
- require_once('util.age_string.php');
  require_once('util.epochcmp.php');
- require_once('gitutil.git_get_type.php');
  require_once('gitutil.git_read_hash.php');
- require_once('gitutil.git_read_tag.php');
- require_once('gitutil.git_read_commit.php');
+ require_once('gitutil.git_read_ref.php');
+ require_once('gitutil.git_read_packed_refs.php');
 
 function git_read_refs($projectroot,$project,$refdir)
 {
@@ -40,44 +38,26 @@
 	$reflist = array();
 	foreach ($refs as $i => $ref_file) {
 		$ref_id = git_read_hash($projectroot . $project . "/" . $refdir . "/" . $ref_file);
-		$type = git_get_type($projectroot . $project, $ref_id);
-		if ($type) {
-			$ref_item = array();
-			$ref_item['type'] = $type;
-			$ref_item['id'] = $ref_id;
-			$ref_item['epoch'] = 0;
-			$ref_item['age_string'] = "unknown";
+		$refobj = git_read_ref($projectroot, $project, $ref_id, $ref_file);
+		if (isset($refobj))
+			$reflist[] = $refobj;
+	}
 
-			if ($type == "tag") {
-				$tag = git_read_tag($projectroot . $project, $ref_id);
-				$ref_item['comment'] = $tag['comment'];
-				if ($tag['type'] == "commit") {
-					$co = git_read_commit($projectroot . $project, $tag['object']);
-					$ref_item['epoch'] = $co['committer_epoch'];
-					$ref_item['age_string'] = $co['age_string'];
-					$ref_item['age'] = $co['age'];
-				} else if (isset($tag['epoch'])) {
-					$age = time() - $tag['epoch'];
-					$ref_item['epoch'] = $tag['epoch'];
-					$ref_item['age_string'] = age_string($age);
-					$ref_item['age'] = $age;
+	$packedrefs = git_read_packed_refs($projectroot, $project, $refdir);
+	if (isset($packedrefs) && count($packedrefs) > 0) {
+		foreach ($packedrefs as $packedref) {
+			$found = false;
+			foreach ($reflist as $ref) {
+				if (strcmp($ref["name"], $packedref["name"]) === 0) {
+					$found = true;
+					break;
 				}
-				$ref_item['reftype'] = $tag['type'];
-				$ref_item['name'] = $tag['name'];
-				$ref_item['refid'] = $tag['object'];
-			} else if ($type == "commit") {
-				$co = git_read_commit($projectroot . $project, $ref_id);
-				$ref_item['reftype'] = "commit";
-				$ref_item['name'] = $ref_file;
-				$ref_item['title'] = $co['title'];
-				$ref_item['refid'] = $ref_id;
-				$ref_item['epoch'] = $co['committer_epoch'];
-				$ref_item['age_string'] = $co['age_string'];
-				$ref_item['age'] = $co['age'];
 			}
-			$reflist[] = $ref_item;
+			if (!$found)
+				$reflist[] = $packedref;
 		}
 	}
+
 	usort($reflist,"epochcmp");
 	return $reflist;
 }

comments