]> source.dussan.org Git - jgit.git/commitdiff
Allow lookup of multiple exact refs in one shot 77/49577/2
authorJonathan Nieder <jrn@google.com>
Fri, 5 Jun 2015 23:08:55 +0000 (16:08 -0700)
committerJonathan Nieder <jrn@google.com>
Fri, 5 Jun 2015 23:08:55 +0000 (16:08 -0700)
exactRef(ref1, ref2, ref3) requests multiple specific refs in a single
lookup, which may be faster in some backends than looking them up one by
one.

firstExactRef generalizes getRef by finding the first existing ref from
the list of refs named.  Its main purpose is for the default
implementation of getRef (finding the first existing ref in a search
path).  Hopefully it can be useful for other operations that look for
refs in a search path (e.g., git log --notes=<name>), too.

Change-Id: I5c6fcf1d3920f6968b8b97f3d4c3a267258c4b86
Signed-off-by: Jonathan Nieder <jrn@google.com>
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java
org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java

index 292e50447e499a10c2128293bb0362c23c0745f7..0991598920a2cb3cb2508960d16a479d53496a22 100644 (file)
@@ -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<String, Ref> 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<String, Ref> tags;
index 1a58c5138233113b4e1f19c3ad0b08db275f3e43..fd99e4d0382be6aa549d9434d463189dd5a2c0e0 100644 (file)
@@ -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.
+        * <p>
+        * 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<String, Ref> exactRef(String... refs) throws IOException {
+               Map<String, Ref> 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.
+        * <p>
+        * 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.
         *