RefDirectory.exactRef: Do not ignore symrefs to unborn branch
When asked to read a symref pointing to a branch-yet-to-be-born (such as HEAD in a newly initialized repository), DfsRepository and FileRepository return different results. FileRepository: exactRef("HEAD") => null DfsRepository: exactRef("HEAD") => SymbolicRef[HEAD -> refs/heads/master=00000000] getRef("HEAD") returns the same as DfsRepository's exactRef in both backends. The intended behavior is the DfsRepository one: exactRef() is supposed to be like getRef(), but more exact because it doesn't need to traverse the search path. The discrepancy is because DfsRefDatabase implements exactRef() directly with the intended semantics, while RefDirectory uses a fallback implementation built on top of getRefs(). getRefs() skips symrefs to an unborn branch. Override the fallback implementation with a correct implementation that is similar to getRef() to avoid this. A followup change will fix the fallback. Change-Id: Ic138a5564a099ebf32248d86b93e2de9ab3c94ee Reported-by: David Pursehouse <david.pursehouse@sonymobile.com> Improved-by: Christian Halstrick <christian.halstrick@sap.com> Bug: 478865
This commit is contained in:
parent
ee66914e41
commit
797f94d331
|
@ -1024,6 +1024,25 @@ public void testGetRef_EmptyDatabase() throws IOException {
|
|||
assertNull(refdir.getRef("v1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExactRef_EmptyDatabase() throws IOException {
|
||||
Ref r;
|
||||
|
||||
r = refdir.exactRef(HEAD);
|
||||
assertTrue(r.isSymbolic());
|
||||
assertSame(LOOSE, r.getStorage());
|
||||
assertEquals("refs/heads/master", r.getTarget().getName());
|
||||
assertSame(NEW, r.getTarget().getStorage());
|
||||
assertNull(r.getTarget().getObjectId());
|
||||
|
||||
assertNull(refdir.exactRef("refs/heads/master"));
|
||||
assertNull(refdir.exactRef("refs/tags/v1.0"));
|
||||
assertNull(refdir.exactRef("FETCH_HEAD"));
|
||||
assertNull(refdir.exactRef("NOT.A.REF.NAME"));
|
||||
assertNull(refdir.exactRef("master"));
|
||||
assertNull(refdir.exactRef("v1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRef_FetchHead() throws IOException {
|
||||
// This is an odd special case where we need to make sure we read
|
||||
|
|
|
@ -261,6 +261,30 @@ private RefList<LooseRef> getLooseRefs() {
|
|||
return loose;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ref exactRef(String name) throws IOException {
|
||||
RefList<Ref> packed = getPackedRefs();
|
||||
Ref ref;
|
||||
try {
|
||||
ref = readRef(name, packed);
|
||||
if (ref != null) {
|
||||
ref = resolve(ref, 0, null, null, packed);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (name.contains("/") //$NON-NLS-1$
|
||||
|| !(e.getCause() instanceof InvalidObjectIdException)) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
// While looking for a ref outside of refs/ (e.g., 'config'), we
|
||||
// found a non-ref file (e.g., a config file) instead. Treat this
|
||||
// as a ref-not-found condition.
|
||||
ref = null;
|
||||
}
|
||||
fireRefsChanged();
|
||||
return ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ref getRef(final String needle) throws IOException {
|
||||
final RefList<Ref> packed = getPackedRefs();
|
||||
|
|
Loading…
Reference in New Issue