[PATCH] Implement packed refs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Robin Rosenberg <robin.rosenberg@xxxxxxxxxx>
---
 .../src/org/spearce/jgit/lib/Repository.java       |   48 +++++++++++++++++++-
 .../tst/org/spearce/jgit/lib/T0003_Basic.java      |   44 ++++++++++++++++++
 2 files changed, 91 insertions(+), 1 deletions(-)

diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
index 76191be..3b2a82c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java
@@ -399,6 +399,7 @@ public class Repository {
 
 	private Ref readRef(final String revstr, final boolean missingOk)
 			throws IOException {
+		refreshPackredRefsCache();
 		for (int k = 0; k < refSearchPaths.length; k++) {
 			final Ref r = readRefBasic(refSearchPaths[k] + revstr);
 			if (missingOk || r.getObjectId() != null) {
@@ -411,6 +412,10 @@ public class Repository {
 	private Ref readRefBasic(String name) throws IOException {
 		int depth = 0;
 		REF_READING: do {
+			ObjectId id = packedRefs.get(name);
+			if (id != null)
+				return new Ref(null, id);
+
 			final File f = new File(getDirectory(), name);
 			if (!f.isFile()) {
 				return new Ref(f, null);
@@ -470,7 +475,43 @@ public class Repository {
 	}
 
 	public Collection<String> getTags() {
-		return listFilesRecursively(new File(refsDir, "tags"), null);
+		Collection<String> tags = listFilesRecursively(new File(refsDir, "tags"), null);
+		refreshPackredRefsCache();
+		tags.addAll(packedRefs.keySet());
+		return tags;
+	}
+
+	private Map<String,ObjectId> packedRefs = new HashMap<String,ObjectId>();
+	private long packedrefstime = 0;
+
+	private void refreshPackredRefsCache() {
+		File file = new File(gitDir, "packed-refs");
+		if (!file.exists()) {
+			if (packedRefs.size() > 0)
+				packedRefs = new HashMap();
+			return;
+		}
+		if (file.lastModified() == packedrefstime)
+			return;
+		Map newPackedRefs = new HashMap();
+		try {
+			BufferedReader b=new BufferedReader(new FileReader(file));
+			String p;
+			while ((p = b.readLine()) != null) {
+				if (p.charAt(0) == '#')
+					continue;
+				if (p.charAt(0) == '^') {
+					continue;
+				}
+				int spos = p.indexOf(' ');
+				ObjectId id = new ObjectId(p.substring(0,spos));
+				String name = p.substring(spos+1);
+				newPackedRefs.put(name, id);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		packedRefs = newPackedRefs;
 	}
 
 	/**
@@ -551,4 +592,9 @@ public class Repository {
 		}
 		return ret;
 	}
+	
+	/** Clean up stale caches */
+	public void refreshFromDisk() {
+		packedRefs = null;
+	}
 }
diff --git a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0003_Basic.java b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0003_Basic.java
index 2f76907..02ecabf 100644
--- a/org.spearce.jgit/tst/org/spearce/jgit/lib/T0003_Basic.java
+++ b/org.spearce.jgit/tst/org/spearce/jgit/lib/T0003_Basic.java
@@ -21,6 +21,7 @@ import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.PrintWriter;
 
 public class T0003_Basic extends RepositoryTestCase {
 	public void test001_Initalize() {
@@ -428,4 +429,47 @@ public class T0003_Basic extends RepositoryTestCase {
 		ObjectId cid = new ObjectWriter(db).writeCommit(commit);
 		assertEquals("2979b39d385014b33287054b87f77bcb3ecb5ebf", cid.toString());
 	}
+	
+	public void test025_packedRefs() throws IOException {
+		test020_createBlobTag();
+		test021_createTreeTag();
+		test022_createCommitTag();
+
+		if (!new File(db.getDirectory(),"refs/tags/test020").delete()) throw new Error("Cannot delete unpacked tag");
+		if (!new File(db.getDirectory(),"refs/tags/test021").delete()) throw new Error("Cannot delete unpacked tag");
+		if (!new File(db.getDirectory(),"refs/tags/test022").delete()) throw new Error("Cannot delete unpacked tag");
+
+		// We cannot resolve it now, since we have no ref
+		Tag mapTag20missing = db.mapTag("test020");
+		assertNull(mapTag20missing);
+
+		// Construct packed refs file
+		PrintWriter w = new PrintWriter(new FileWriter(new File(db.getDirectory(), "packed-refs")));
+		w.println("# packed-refs with: peeled");
+		w.println("6759556b09fbb4fd8ae5e315134481cc25d46954 refs/tags/test020");
+		w.println("^e69de29bb2d1d6434b8b29ae775ad8c2e48c5391");
+		w.println("b0517bc8dbe2096b419d42424cd7030733f4abe5 refs/tags/test021");
+		w.println("^417c01c8795a35b8e835113a85a5c0c1c77f67fb");
+		w.println("0ce2ebdb36076ef0b38adbe077a07d43b43e3807 refs/tags/test022");
+		w.println("^b5d3b45a96b340441f5abb9080411705c51cc86c");
+		w.close();
+
+		Tag mapTag20 = db.mapTag("test020");
+		assertEquals("blob", mapTag20.getType());
+		assertEquals("test020 tagged\n", mapTag20.getMessage());
+		assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag20.getAuthor());
+		assertEquals("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", mapTag20.getObjId().toString());
+
+		Tag mapTag21 = db.mapTag("test021");
+		assertEquals("tree", mapTag21.getType());
+		assertEquals("test021 tagged\n", mapTag21.getMessage());
+		assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag21.getAuthor());
+		assertEquals("417c01c8795a35b8e835113a85a5c0c1c77f67fb", mapTag21.getObjId().toString());
+
+		Tag mapTag22 = db.mapTag("test022");
+		assertEquals("commit", mapTag22.getType());
+		assertEquals("test022 tagged\n", mapTag22.getMessage());
+		assertEquals(new PersonIdent(jauthor, 1154236443000L, -4 * 60), mapTag22.getAuthor());
+		assertEquals("b5d3b45a96b340441f5abb9080411705c51cc86c", mapTag22.getObjId().toString());
+	}
 }
-- 
1.5.1.1

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux