Also adds a few some more test for refs, though not complete. Signed-off-by: Robin Rosenberg <robin.rosenberg@xxxxxxxxxx> --- .../tst/org/spearce/jgit/lib/RefTest.java | 94 ++++++++++++++++++++ .../src/org/spearce/jgit/lib/RefDatabase.java | 26 ++++-- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefTest.java index cae5143..7b0c9a9 100644 --- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefTest.java +++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/RefTest.java @@ -36,8 +36,14 @@ */ package org.spearce.jgit.lib; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.Map; +import org.spearce.jgit.lib.Ref.Storage; +import org.spearce.jgit.lib.RefUpdate.Result; + /** * Misc tests for refs. A lot of things are tested elsewhere so not having a * test for a ref related method, does not mean it is untested. @@ -69,4 +75,92 @@ public void testReadAllIncludingSymrefs() throws Exception { assertFalse(refmaster.isPeeled()); assertNull(refmaster.getPeeledObjectId()); } + + public void testReadSymRefToPacked() throws IOException { + db.writeSymref("HEAD", "refs/heads/master"); + Ref ref = db.getRef("HEAD"); + assertEquals(Ref.Storage.LOOSE, ref.getStorage()); + } + + public void testReadSymRefToLoosePacked() throws IOException { + ObjectId pid = db.resolve("refs/heads/master^"); + RefUpdate updateRef = db.updateRef("refs/heads/master"); + updateRef.setNewObjectId(pid); + updateRef.setForceUpdate(true); + Result update = updateRef.update(); + assertEquals(Result.FORCED, update); // internal + + db.writeSymref("HEAD", "refs/heads/master"); + Ref ref = db.getRef("HEAD"); + assertEquals(Ref.Storage.LOOSE, ref.getStorage()); + } + + public void testReadLooseRef() throws IOException { + RefUpdate updateRef = db.updateRef("ref/heads/new"); + updateRef.setNewObjectId(db.resolve("refs/heads/master")); + Result update = updateRef.update(); + assertEquals(Result.NEW, update); + Ref ref = db.getRef("ref/heads/new"); + assertEquals(Storage.LOOSE, ref.getStorage()); + } + + /** + * Let an "outsider" create a loose ref with the same name as a packed one + * + * @throws IOException + * @throws InterruptedException + */ + public void testReadLoosePackedRef() throws IOException, + InterruptedException { + Ref ref = db.getRef("refs/heads/master"); + assertEquals(Storage.PACKED, ref.getStorage()); + FileOutputStream os = new FileOutputStream(new File(db.getDirectory(), + "refs/heads/master")); + os.write(ref.getObjectId().name().getBytes()); + os.write('\n'); + os.close(); + + ref = db.getRef("refs/heads/master"); + assertEquals(Storage.LOOSE_PACKED, ref.getStorage()); + } + + /** + * Modify a packed ref using the API. This creates a loose ref too, ie. + * LOOSE_PACKED + * + * @throws IOException + */ + public void testReadSimplePackedRefSameRepo() throws IOException { + Ref ref = db.getRef("refs/heads/master"); + ObjectId pid = db.resolve("refs/heads/master^"); + assertEquals(Storage.PACKED, ref.getStorage()); + RefUpdate updateRef = db.updateRef("refs/heads/master"); + updateRef.setNewObjectId(pid); + updateRef.setForceUpdate(true); + Result update = updateRef.update(); + assertEquals(Result.FORCED, update); + + ref = db.getRef("refs/heads/master"); + assertEquals(Storage.LOOSE_PACKED, ref.getStorage()); + } + + /** + * Delete a ref that exists both as packed and loose. Make sure the ref + * cannot be resolved after delete. + * + * @throws IOException + */ + public void testDeleteLoosePacked() throws IOException { + ObjectId pid = db.resolve("refs/heads/master^"); + RefUpdate updateRef = db.updateRef("refs/heads/master"); + updateRef.setNewObjectId(pid); + updateRef.setForceUpdate(true); + Result update = updateRef.update(); + assertEquals(Result.FORCED, update); // internal + + RefUpdate updateRef2 = db.updateRef("refs/heads/master"); + Result delete = updateRef2.delete(); + assertEquals(Result.FORCED, delete); + assertNull(db.resolve("refs/heads/master")); + } } diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java index 155ed9a..573fcac 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java @@ -283,8 +283,14 @@ private synchronized Ref readRefBasic(final String origName, final long mtime = loose.lastModified(); if (ref != null) { Long cachedlastModified = looseRefsMTime.get(name); - if (cachedlastModified != null && cachedlastModified == mtime) - return ref; + if (cachedlastModified != null && cachedlastModified == mtime) { + if (packedRefs.containsKey(origName)) + return new Ref(Storage.LOOSE_PACKED, origName, ref + .getObjectId(), ref.getPeeledObjectId(), ref + .isPeeled()); + else + return ref; + } looseRefs.remove(origName); looseRefsMTime.remove(origName); } @@ -349,12 +355,20 @@ private synchronized Ref readRefBasic(final String origName, throw new IOException("Not a ref: " + name + ": " + line); } - ref = new Ref(Ref.Storage.LOOSE, origName, name, id); - - looseRefs.put(origName, ref); - ref = new Ref(Ref.Storage.LOOSE, origName, id); + Storage storage; + if (packedRefs.containsKey(name)) + storage = Ref.Storage.LOOSE_PACKED; + else + storage = Ref.Storage.LOOSE; + ref = new Ref(storage, name, id); looseRefs.put(name, ref); looseRefsMTime.put(name, mtime); + + if (!origName.equals(name)) { + ref = new Ref(Ref.Storage.LOOSE, origName, name, id); + looseRefs.put(origName, ref); + } + return ref; } -- 1.6.3.dirty -- 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