InMemoryRepository: Ensure new ref targets exist in the repo
ObjectInserter recently learned to read back inserted objects before they have been flushed. It is in general unsafe to create refs to such objects, but it is now much more possible to do so, by passing "new RevWalk(inserter.newReader())" into RefUpdate#execute(RevWalk). We can't change the RefUpdate interface to remove execute(RevWalk); nor would we necessarily want to, for performance reasons. And in any case, RefUpdate#safeParse explicitly ignores MissingObjectExceptions. But we can enforce object existence in InMemoryRepository, which will allow callers using this class in their tests to ensure they are using the RefDatabase correctly. Change-Id: I5c696ba23bcd2a536a0512fa7f5b6130961905c5
This commit is contained in:
parent
e314e42d41
commit
d612468c5c
|
@ -14,8 +14,10 @@
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jgit.internal.storage.pack.PackExt;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Ref.Storage;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.util.RefList;
|
||||
|
||||
/**
|
||||
|
@ -241,6 +243,17 @@ protected RefCache scanAllRefs() throws IOException {
|
|||
@Override
|
||||
protected boolean compareAndPut(Ref oldRef, Ref newRef)
|
||||
throws IOException {
|
||||
ObjectId id = newRef.getObjectId();
|
||||
if (id != null) {
|
||||
RevWalk rw = new RevWalk(getRepository());
|
||||
try {
|
||||
// Validate that the target exists in a new RevWalk, as the RevWalk
|
||||
// from the RefUpdate might be reading back unflushed objects.
|
||||
rw.parseAny(id);
|
||||
} finally {
|
||||
rw.release();
|
||||
}
|
||||
}
|
||||
String name = newRef.getName();
|
||||
if (oldRef == null || oldRef.getStorage() == Storage.NEW)
|
||||
return refs.putIfAbsent(name, newRef) == null;
|
||||
|
|
Loading…
Reference in New Issue