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