If an ObjectInserter is created from a CachedObjectDirectory, we need to ensure the cache is updated whenever a new loose object is actually added to the loose objects directory, otherwise a future read from an ObjectReader on the CachedObjectDirectory might not be able to open the newly created object. We mostly had the infrastructure in place to implement this due to the injection of unpacked large deltas, but we didn't have a way to pass the ObjectId from ObjectDirectoryInserter to CachedObjectDirectory, because the inserter was using the underlying ObjectDirectory and not the CachedObjectDirectory. Redirecting to CachedObjectDirectory ensures the cache is updated. Change-Id: I1f7bdfacc7ad77ebdb885f655e549cc570652225 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>tags/v0.10.1
import org.eclipse.jgit.lib.AbbreviatedObjectId; | import org.eclipse.jgit.lib.AbbreviatedObjectId; | ||||
import org.eclipse.jgit.lib.AnyObjectId; | import org.eclipse.jgit.lib.AnyObjectId; | ||||
import org.eclipse.jgit.lib.Config; | |||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.ObjectDatabase; | import org.eclipse.jgit.lib.ObjectDatabase; | ||||
import org.eclipse.jgit.lib.ObjectId; | import org.eclipse.jgit.lib.ObjectId; | ||||
// Don't close anything. | // Don't close anything. | ||||
} | } | ||||
@Override | |||||
public ObjectDirectoryInserter newInserter() { | |||||
return wrapped.newInserter(); | |||||
} | |||||
@Override | @Override | ||||
public ObjectDatabase newCachedDatabase() { | public ObjectDatabase newCachedDatabase() { | ||||
return this; | return this; | ||||
return wrapped.getDirectory(); | return wrapped.getDirectory(); | ||||
} | } | ||||
@Override | |||||
Config getConfig() { | |||||
return wrapped.getConfig(); | |||||
} | |||||
@Override | @Override | ||||
AlternateHandle[] myAlternates() { | AlternateHandle[] myAlternates() { | ||||
if (alts == null) { | if (alts == null) { |
import org.eclipse.jgit.lib.AbbreviatedObjectId; | import org.eclipse.jgit.lib.AbbreviatedObjectId; | ||||
import org.eclipse.jgit.lib.AnyObjectId; | import org.eclipse.jgit.lib.AnyObjectId; | ||||
import org.eclipse.jgit.lib.Config; | |||||
import org.eclipse.jgit.lib.ObjectDatabase; | import org.eclipse.jgit.lib.ObjectDatabase; | ||||
import org.eclipse.jgit.lib.ObjectId; | import org.eclipse.jgit.lib.ObjectId; | ||||
import org.eclipse.jgit.lib.ObjectLoader; | import org.eclipse.jgit.lib.ObjectLoader; | ||||
} | } | ||||
@Override | @Override | ||||
public abstract ObjectDirectoryInserter newInserter(); | |||||
public ObjectDirectoryInserter newInserter() { | |||||
return new ObjectDirectoryInserter(this, getConfig()); | |||||
} | |||||
/** | /** | ||||
* Does the requested object exist in this database? | * Does the requested object exist in this database? | ||||
return hasObjectImpl1(objectId) || hasObjectImpl2(objectId.name()); | return hasObjectImpl1(objectId) || hasObjectImpl2(objectId.name()); | ||||
} | } | ||||
/** | |||||
* Compute the location of a loose object file. | |||||
* | |||||
* @param objectId | |||||
* identity of the loose object to map to the directory. | |||||
* @return location of the object, if it were to exist as a loose object. | |||||
*/ | |||||
File fileFor(final AnyObjectId objectId) { | |||||
return fileFor(objectId.name()); | |||||
} | |||||
File fileFor(final String objectName) { | |||||
final String d = objectName.substring(0, 2); | |||||
final String f = objectName.substring(2); | |||||
return new File(new File(getDirectory(), d), f); | |||||
} | |||||
final boolean hasObjectImpl1(final AnyObjectId objectId) { | final boolean hasObjectImpl1(final AnyObjectId objectId) { | ||||
if (hasObject1(objectId)) | if (hasObject1(objectId)) | ||||
return true; | return true; | ||||
abstract void resolve(Set<ObjectId> matches, AbbreviatedObjectId id) | abstract void resolve(Set<ObjectId> matches, AbbreviatedObjectId id) | ||||
throws IOException; | throws IOException; | ||||
abstract Config getConfig(); | |||||
/** | /** | ||||
* Open an object from this database. | * Open an object from this database. | ||||
* <p> | * <p> |
* identity of the loose object to map to the directory. | * identity of the loose object to map to the directory. | ||||
* @return location of the object, if it were to exist as a loose object. | * @return location of the object, if it were to exist as a loose object. | ||||
*/ | */ | ||||
@Override | |||||
public File fileFor(final AnyObjectId objectId) { | public File fileFor(final AnyObjectId objectId) { | ||||
return fileFor(objectId.name()); | |||||
} | |||||
private File fileFor(final String objectName) { | |||||
final String d = objectName.substring(0, 2); | |||||
final String f = objectName.substring(2); | |||||
return new File(new File(objects, d), f); | |||||
return super.fileFor(objectId); | |||||
} | } | ||||
/** | /** | ||||
return false; | return false; | ||||
} | } | ||||
Config getConfig() { | |||||
return config; | |||||
} | |||||
private void insertPack(final PackFile pf) { | private void insertPack(final PackFile pf) { | ||||
PackList o, n; | PackList o, n; | ||||
do { | do { |
/** Creates loose objects in a {@link ObjectDirectory}. */ | /** Creates loose objects in a {@link ObjectDirectory}. */ | ||||
class ObjectDirectoryInserter extends ObjectInserter { | class ObjectDirectoryInserter extends ObjectInserter { | ||||
private final ObjectDirectory db; | |||||
private final FileObjectDatabase db; | |||||
private final Config config; | private final Config config; | ||||
private Deflater deflate; | private Deflater deflate; | ||||
ObjectDirectoryInserter(final ObjectDirectory dest, final Config cfg) { | |||||
ObjectDirectoryInserter(final FileObjectDatabase dest, final Config cfg) { | |||||
db = dest; | db = dest; | ||||
config = cfg; | config = cfg; | ||||
} | } |