diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java index 292e50447..099159892 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java @@ -358,6 +358,33 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase { assertEquals(A, c.getObjectId()); } + @Test + public void testFirstExactRef_IgnoresGarbageRef() throws IOException { + writeLooseRef("refs/heads/A", A); + write(new File(diskRepo.getDirectory(), "refs/heads/bad"), "FAIL\n"); + + Ref a = refdir.firstExactRef("refs/heads/bad", "refs/heads/A"); + assertEquals("refs/heads/A", a.getName()); + assertEquals(A, a.getObjectId()); + } + + @Test + public void testExactRef_IgnoresGarbageRef() throws IOException { + writeLooseRef("refs/heads/A", A); + write(new File(diskRepo.getDirectory(), "refs/heads/bad"), "FAIL\n"); + + Map refs = + refdir.exactRef("refs/heads/bad", "refs/heads/A"); + + assertNull("no refs/heads/bad", refs.get("refs/heads/bad")); + + Ref a = refs.get("refs/heads/A"); + assertEquals("refs/heads/A", a.getName()); + assertEquals(A, a.getObjectId()); + + assertEquals(1, refs.size()); + } + @Test public void testGetRefs_InvalidName() throws IOException { writeLooseRef("refs/heads/A", A); @@ -463,6 +490,21 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase { assertEquals(B, b.getObjectId()); } + @Test + public void testFirstExactRef_Mixed() throws IOException { + writeLooseRef("refs/heads/A", A); + writePackedRef("refs/tags/v1.0", v1_0); + + Ref a = refdir.firstExactRef("refs/heads/A", "refs/tags/v1.0"); + Ref one = refdir.firstExactRef("refs/tags/v1.0", "refs/heads/A"); + + assertEquals("refs/heads/A", a.getName()); + assertEquals("refs/tags/v1.0", one.getName()); + + assertEquals(A, a.getObjectId()); + assertEquals(v1_0, one.getObjectId()); + } + @Test public void testGetRefs_TagsOnly_AllLoose() throws IOException { Map tags; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java index 1a58c5138..fd99e4d03 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java @@ -47,6 +47,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -254,6 +255,55 @@ public abstract class RefDatabase { return null; } + /** + * Read the specified references. + *

+ * This method expects a list of unshortened reference names and returns + * a map from reference names to refs. Any named references that do not + * exist will not be included in the returned map. + * + * @param refs + * the unabbreviated names of references to look up. + * @return modifiable map describing any refs that exist among the ref + * ref names supplied. The map can be an unsorted map. + * @throws IOException + * the reference space cannot be accessed. + * @since 4.1 + */ + public Map exactRef(String... refs) throws IOException { + Map result = new HashMap<>(refs.length); + for (String name : refs) { + Ref ref = exactRef(name); + if (ref != null) { + result.put(name, ref); + } + } + return result; + } + + /** + * Find the first named reference. + *

+ * This method expects a list of unshortened reference names and returns + * the first that exists. + * + * @param refs + * the unabbreviated names of references to look up. + * @return the first named reference that exists (if any); else {@code null}. + * @throws IOException + * the reference space cannot be accessed. + * @since 4.1 + */ + public Ref firstExactRef(String... refs) throws IOException { + for (String name : refs) { + Ref ref = exactRef(name); + if (ref != null) { + return ref; + } + } + return null; + } + /** * Get a section of the reference namespace. *