assertNull(r.getPeeledObjectId());
}
+ @Test
+ public void testExactRef_FetchHead() throws IOException {
+ // This is an odd special case where we need to make sure we read
+ // exactly the first 40 bytes of the file and nothing further on
+ // that line, or the remainder of the file.
+ write(new File(diskRepo.getDirectory(), "FETCH_HEAD"), A.name()
+ + "\tnot-for-merge"
+ + "\tbranch 'master' of git://egit.eclipse.org/jgit\n");
+
+ Ref r = refdir.exactRef("FETCH_HEAD");
+ assertFalse(r.isSymbolic());
+ assertEquals(A, r.getObjectId());
+ assertEquals("FETCH_HEAD", r.getName());
+ assertFalse(r.isPeeled());
+ assertNull(r.getPeeledObjectId());
+ }
+
@Test
public void testGetRef_AnyHeadWithGarbage() throws IOException {
write(new File(diskRepo.getDirectory(), "refs/heads/A"), A.name()
}
}
+ private void writeNewRef(String name, ObjectId value) throws IOException {
+ RefUpdate updateRef = db.updateRef(name);
+ updateRef.setNewObjectId(value);
+ assertEquals(RefUpdate.Result.NEW, updateRef.update());
+ }
+
@Test
public void testRemoteNames() throws Exception {
FileBasedConfig config = db.getConfig();
assertEquals(Storage.LOOSE, ref.getStorage());
}
+ @Test
+ public void testGetShortRef() throws IOException {
+ Ref ref = db.getRef("master");
+ assertEquals("refs/heads/master", ref.getName());
+ assertEquals(db.resolve("refs/heads/master"), ref.getObjectId());
+ }
+
+ @Test
+ public void testGetShortExactRef() throws IOException {
+ assertNull(db.getRefDatabase().exactRef("master"));
+
+ Ref ref = db.getRefDatabase().exactRef("HEAD");
+ assertEquals("HEAD", ref.getName());
+ assertEquals("refs/heads/master", ref.getTarget().getName());
+ assertEquals(db.resolve("refs/heads/master"), ref.getObjectId());
+ }
+
+ @Test
+ public void testRefsUnderRefs() throws IOException {
+ ObjectId masterId = db.resolve("refs/heads/master");
+ writeNewRef("refs/heads/refs/foo/bar", masterId);
+
+ assertNull(db.getRefDatabase().exactRef("refs/foo/bar"));
+
+ Ref ref = db.getRef("refs/foo/bar");
+ assertEquals("refs/heads/refs/foo/bar", ref.getName());
+ assertEquals(db.resolve("refs/heads/master"), ref.getObjectId());
+ }
+
+ @Test
+ public void testAmbiguousRefsUnderRefs() throws IOException {
+ ObjectId masterId = db.resolve("refs/heads/master");
+ writeNewRef("refs/foo/bar", masterId);
+ writeNewRef("refs/heads/refs/foo/bar", masterId);
+
+ Ref exactRef = db.getRefDatabase().exactRef("refs/foo/bar");
+ assertEquals("refs/foo/bar", exactRef.getName());
+ assertEquals(masterId, exactRef.getObjectId());
+
+ Ref ref = db.getRef("refs/foo/bar");
+ assertEquals("refs/foo/bar", ref.getName());
+ assertEquals(masterId, ref.getObjectId());
+ }
+
/**
* Let an "outsider" create a loose ref with the same name as a packed one
*
* Aside from taking advantage of {@link #SEARCH_PATH}, this method may be
* able to more quickly resolve a single reference name than obtaining the
* complete namespace by {@code getRefs(ALL).get(name)}.
+ * <p>
+ * To read a specific reference without using @{link #SEARCH_PATH}, see
+ * {@link #exactRef(String)}.
*
* @param name
* the name of the reference. May be a short name which must be
*/
public abstract Ref getRef(String name) throws IOException;
+ /**
+ * Read a single reference.
+ * <p>
+ * Unlike {@link #getRef}, this method expects an unshortened reference
+ * name and does not search using the standard {@link #SEARCH_PATH}.
+ *
+ * @param name
+ * the unabbreviated name of the reference.
+ * @return the reference (if it exists); else {@code null}.
+ * @throws IOException
+ * the reference space cannot be accessed.
+ * @since 4.1
+ */
+ public Ref exactRef(String name) throws IOException {
+ int slash = name.lastIndexOf('/');
+ String prefix = name.substring(0, slash + 1);
+ String rest = name.substring(slash + 1);
+ Ref result = getRefs(prefix).get(rest);
+ if (result != null || slash != -1) {
+ return result;
+ }
+
+ for (Ref ref : getAdditionalRefs()) {
+ if (name.equals(ref.getName())) {
+ return ref;
+ }
+ }
+ return null;
+ }
+
/**
* Get a section of the reference namespace.
*
* The result list includes non-ref items such as MERGE_HEAD and
* FETCH_RESULT cast to be refs. The names of these refs are not returned by
* <code>getRefs(ALL)</code> but are accepted by {@link #getRef(String)}
+ * and {@link exactRef(String)}.
*
* @return a list of additional refs
* @throws IOException