Replace WindowCache with ObjectReader

The WindowCache is an implementation detail of PackFile and how its
used by ObjectDirectory.  Lets start to hide it and replace the public
API with a more generic concept, ObjectReader.

Because PackedObjectLoader is also considered a private detail of
PackFile, we have to make PackWriter temporarily dependent upon the
WindowCursor and thus FileRepository and ObjectDirectory in order to
just start the refactoring.  In later changes we will clean up the
APIs more, exposing sufficient support to PackWriter without needing
the file specific implementation details.

Change-Id: I676be12b57f3534f1285854ee5de1aa483895398
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Shawn O. Pearce 2010-06-18 23:02:57 -07:00
parent 133c987f4d
commit 5cfc29b491
20 changed files with 274 additions and 157 deletions

View File

@ -86,7 +86,7 @@
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
@ -144,7 +144,7 @@ public class IpLogGenerator {
private NameConflictTreeWalk tw;
private final WindowCursor curs = new WindowCursor();
private ObjectReader curs;
private final MutableObjectId idbuf = new MutableObjectId();
@ -184,6 +184,7 @@ public void scan(Repository repo, RevCommit startCommit, String version)
throws IOException, ConfigInvalidException {
try {
db = repo;
curs = db.newObjectReader();
rw = new RevWalk(db);
tw = new NameConflictTreeWalk(db);
@ -194,7 +195,7 @@ public void scan(Repository repo, RevCommit startCommit, String version)
scanProjectCommits(meta.getProjects().get(0), c);
commits.add(c);
} finally {
WindowCursor.release(curs);
curs.release();
db = null;
rw = null;
tw = null;

View File

@ -59,7 +59,7 @@
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.pgm.CLIText;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
@ -121,7 +121,7 @@ public int parseArguments(final Parameters params) throws CmdLineException {
throw new CmdLineException(MessageFormat.format(CLIText.get().notATree, name));
final CanonicalTreeParser p = new CanonicalTreeParser();
final WindowCursor curs = new WindowCursor();
final ObjectReader curs = clp.getRepository().newObjectReader();
try {
p.reset(clp.getRepository(), clp.getRevWalk().parseTree(id), curs);
} catch (MissingObjectException e) {

View File

@ -63,7 +63,7 @@ public void test003_lookupCompressedObject() throws IOException {
id = ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327");
pr = new PackFile(TEST_IDX, TEST_PACK);
or = pr.get(new WindowCursor(), id);
or = pr.get(new WindowCursor(null), id);
assertNotNull(or);
assertEquals(Constants.OBJ_TREE, or.getType());
assertEquals(35, or.getSize());

View File

@ -176,7 +176,7 @@ public void testSuccess() throws Exception {
// Verify the only storage of b is our packed delta above.
//
ObjectDirectory od = (ObjectDirectory) src.getObjectDatabase();
assertTrue("has b", od.hasObject(b));
assertTrue("has b", src.hasObject(b));
assertFalse("b not loose", od.fileFor(b).exists());
// Now use b but in a different commit than what is hidden.

View File

@ -51,7 +51,7 @@
import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.TreeWalk;
@ -166,7 +166,7 @@ public void addTree(final byte[] pathPrefix, final int stage,
final Repository db, final AnyObjectId tree) throws IOException {
final TreeWalk tw = new TreeWalk(db);
tw.reset();
final WindowCursor curs = new WindowCursor();
final ObjectReader curs = db.newObjectReader();
try {
tw.addTree(new CanonicalTreeParser(pathPrefix, db, tree
.toObjectId(), curs));

View File

@ -46,7 +46,6 @@
import java.io.File;
import java.io.IOException;
import java.util.Collection;
/**
* The cached instance of an {@link ObjectDirectory}.
@ -116,12 +115,6 @@ FileObjectDatabase newCachedFileObjectDatabase() {
return this;
}
@Override
void openObjectInAllPacks(Collection<PackedObjectLoader> out,
WindowCursor curs, AnyObjectId objectId) throws IOException {
wrapped.openObjectInAllPacks(out, curs, objectId);
}
@Override
File getDirectory() {
return wrapped.getDirectory();
@ -157,7 +150,7 @@ boolean hasObject1(AnyObjectId objectId) {
}
@Override
public ObjectLoader openObject(final WindowCursor curs,
ObjectLoader openObject(final WindowCursor curs,
final AnyObjectId objectId) throws IOException {
return openObjectImpl1(curs, objectId);
}

View File

@ -45,8 +45,14 @@
import java.io.File;
import java.io.IOException;
import java.util.Collection;
abstract class FileObjectDatabase extends ObjectDatabase {
@Override
public ObjectReader newReader() {
return new WindowCursor(this);
}
/**
* Does the requested object exist in this database?
* <p>
@ -98,8 +104,8 @@ final boolean hasObjectImpl2(final String objectId) {
* object, or null if the object does not exist.
* @throws IOException
*/
public ObjectLoader openObject(final WindowCursor curs,
final AnyObjectId objectId) throws IOException {
ObjectLoader openObject(final WindowCursor curs, final AnyObjectId objectId)
throws IOException {
ObjectLoader ldr;
ldr = openObjectImpl1(curs, objectId);
@ -154,6 +160,10 @@ final ObjectLoader openObjectImpl2(final WindowCursor curs,
return null;
}
void openObjectInAllPacks(Collection<PackedObjectLoader> reuseLoaders,
WindowCursor windowCursor, AnyObjectId otp) throws IOException {
}
abstract File getDirectory();
abstract AlternateHandle[] myAlternates();

View File

@ -49,9 +49,7 @@
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import org.eclipse.jgit.JGitText;
@ -396,43 +394,6 @@ public File toFile(final AnyObjectId objectId) {
return objectDatabase.fileFor(objectId);
}
/**
* Open object in all packs containing specified object.
*
* @param objectId
* id of object to search for
* @param curs
* temporary working space associated with the calling thread.
* @return collection of loaders for this object, from all packs containing
* this object
* @throws IOException
*/
public Collection<PackedObjectLoader> openObjectInAllPacks(
final AnyObjectId objectId, final WindowCursor curs)
throws IOException {
Collection<PackedObjectLoader> result = new LinkedList<PackedObjectLoader>();
openObjectInAllPacks(objectId, result, curs);
return result;
}
/**
* Open object in all packs containing specified object.
*
* @param objectId
* id of object to search for
* @param resultLoaders
* result collection of loaders for this object, filled with
* loaders from all packs containing specified object
* @param curs
* temporary working space associated with the calling thread.
* @throws IOException
*/
void openObjectInAllPacks(final AnyObjectId objectId,
final Collection<PackedObjectLoader> resultLoaders,
final WindowCursor curs) throws IOException {
objectDatabase.openObjectInAllPacks(resultLoaders, curs, objectId);
}
/**
* Objects known to exist but not expressed by {@link #getAllRefs()}.
* <p>

View File

@ -44,7 +44,8 @@
package org.eclipse.jgit.lib;
import java.io.IOException;
import java.util.Collection;
import org.eclipse.jgit.errors.MissingObjectException;
/**
* Abstraction of arbitrary object storage.
@ -89,6 +90,17 @@ public void create() throws IOException {
*/
public abstract ObjectInserter newInserter();
/**
* Create a new {@code ObjectReader} to read existing objects.
* <p>
* The returned reader is not itself thread-safe, but multiple concurrent
* reader instances created from the same {@code ObjectDatabase} must be
* thread-safe.
*
* @return reader the caller can use to load objects from this database.
*/
public abstract ObjectReader newReader();
/**
* Close any resources held by this database.
*/
@ -96,42 +108,48 @@ public void create() throws IOException {
/**
* Does the requested object exist in this database?
* <p>
* This is a one-shot call interface which may be faster than allocating a
* {@link #newReader()} to perform the lookup.
*
* @param objectId
* identity of the object to test for existence of.
* @return true if the specified object is stored in this database.
* @throws IOException
* the object store cannot be accessed.
*/
public abstract boolean hasObject(AnyObjectId objectId);
public boolean hasObject(final AnyObjectId objectId) throws IOException {
final ObjectReader or = newReader();
try {
return or.hasObject(objectId);
} finally {
or.release();
}
}
/**
* Open an object from this database.
* <p>
* This is a one-shot call interface which may be faster than allocating a
* {@link #newReader()} to perform the lookup.
*
* @param curs
* temporary working space associated with the calling thread.
* @param objectId
* identity of the object to open.
* @return a {@link ObjectLoader} for accessing the data of the named
* object, or null if the object does not exist.
* @return a {@link ObjectLoader} for accessing the object.
* @throws MissingObjectException
* the object does not exist.
* @throws IOException
* the object store cannot be accessed.
*/
public abstract ObjectLoader openObject(WindowCursor curs,
AnyObjectId objectId) throws IOException;
/**
* Open the object from all packs containing it.
*
* @param out
* result collection of loaders for this object, filled with
* loaders from all packs containing specified object
* @param curs
* temporary working space associated with the calling thread.
* @param objectId
* id of object to search for
* @throws IOException
*/
abstract void openObjectInAllPacks(final Collection<PackedObjectLoader> out,
final WindowCursor curs, final AnyObjectId objectId)
throws IOException;
public ObjectLoader openObject(final AnyObjectId objectId)
throws IOException {
final ObjectReader or = newReader();
try {
return or.openObject(objectId);
} finally {
or.release();
}
}
/**
* Create a new cached database instance over this database. This instance might

View File

@ -283,7 +283,6 @@ ObjectLoader openObject1(final WindowCursor curs,
}
}
@Override
void openObjectInAllPacks(final Collection<PackedObjectLoader> out,
final WindowCursor curs, final AnyObjectId objectId)
throws IOException {
@ -308,6 +307,9 @@ void openObjectInAllPacks(final Collection<PackedObjectLoader> out,
}
break SEARCH;
}
for (AlternateHandle h : myAlternates())
h.db.openObjectInAllPacks(out, curs, objectId);
}
boolean hasObject2(final String objectName) {

View File

@ -0,0 +1,114 @@
/*
* Copyright (C) 2010, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.eclipse.jgit.lib;
import java.io.IOException;
import org.eclipse.jgit.errors.MissingObjectException;
/** Reads an {@link ObjectDatabase} for a single thread. */
public abstract class ObjectReader {
/** Type hint indicating the caller doesn't know the type. */
protected static final int OBJ_ANY = -1;
/**
* Does the requested object exist in this database?
*
* @param objectId
* identity of the object to test for existence of.
* @return true if the specified object is stored in this database.
* @throws IOException
* the object store cannot be accessed.
*/
public boolean hasObject(AnyObjectId objectId) throws IOException {
try {
openObject(objectId);
return true;
} catch (MissingObjectException notFound) {
return false;
}
}
/**
* Open an object from this database.
*
* @param objectId
* identity of the object to open.
* @return a {@link ObjectLoader} for accessing the object.
* @throws MissingObjectException
* the object does not exist.
* @throws IOException
*/
public ObjectLoader openObject(AnyObjectId objectId)
throws MissingObjectException, IOException {
return openObject(objectId, OBJ_ANY);
}
/**
* Open an object from this database.
*
* @param objectId
* identity of the object to open.
*@param typeHint
* hint about the type of object being requested;
* {@link #OBJ_ANY} if the object type is not known, or does not
* matter to the caller.
* @return a {@link ObjectLoader} for accessing the object.
* @throws MissingObjectException
* the object does not exist.
* @throws IOException
*/
public abstract ObjectLoader openObject(AnyObjectId objectId, int typeHint)
throws MissingObjectException, IOException;
/**
* Release any resources used by this reader.
* <p>
* A reader that has been released can be used again, but may need to be
* released after the subsequent usage.
*/
public void release() {
// Do nothing.
}
}

View File

@ -179,7 +179,7 @@ public class PackWriter {
private final byte[] buf = new byte[16384]; // 16 KB
private final WindowCursor windowCursor = new WindowCursor();
private final WindowCursor windowCursor;
private List<ObjectToPack> sortedByName;
@ -236,6 +236,9 @@ public PackWriter(final Repository repo, final ProgressMonitor monitor) {
public PackWriter(final Repository repo, final ProgressMonitor imonitor,
final ProgressMonitor wmonitor) {
this.db = repo;
windowCursor = new WindowCursor((ObjectDirectory) repo
.getObjectDatabase());
initMonitor = imonitor == null ? NullProgressMonitor.INSTANCE : imonitor;
writeMonitor = wmonitor == null ? NullProgressMonitor.INSTANCE : wmonitor;
@ -621,7 +624,7 @@ private void searchForReuse() throws IOException {
private void searchForReuse(
final Collection<PackedObjectLoader> reuseLoaders,
final ObjectToPack otp) throws IOException {
db.openObjectInAllPacks(otp, reuseLoaders, windowCursor);
windowCursor.openObjectInAllPacks(otp, reuseLoaders);
if (reuseDeltas) {
selectDeltaReuseForObject(otp, reuseLoaders);
}

View File

@ -50,7 +50,6 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -64,6 +63,7 @@
import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
@ -153,6 +153,11 @@ public ObjectInserter newObjectInserter() {
return getObjectDatabase().newInserter();
}
/** @return a new inserter to create objects in {@link #getObjectDatabase()} */
public ObjectReader newObjectReader() {
return getObjectDatabase().newReader();
}
/** @return the reference database which stores the reference namespace. */
public abstract RefDatabase getRefDatabase();
@ -186,7 +191,12 @@ public FS getFS() {
* known shared repositories.
*/
public boolean hasObject(AnyObjectId objectId) {
return getObjectDatabase().hasObject(objectId);
try {
return getObjectDatabase().hasObject(objectId);
} catch (IOException e) {
// Legacy API, assume error means "no"
return false;
}
}
/**
@ -199,11 +209,11 @@ public boolean hasObject(AnyObjectId objectId) {
*/
public ObjectLoader openObject(final AnyObjectId id)
throws IOException {
final WindowCursor wc = new WindowCursor();
try {
return openObject(wc, id);
} finally {
wc.release();
return getObjectDatabase().openObject(id);
} catch (MissingObjectException notFound) {
// Legacy API, return null
return null;
}
}
@ -216,43 +226,18 @@ public ObjectLoader openObject(final AnyObjectId id)
* @return a {@link ObjectLoader} for accessing the data of the named
* object, or null if the object does not exist.
* @throws IOException
* @deprecated Use {code newObjectReader().open(id)}.
*/
public ObjectLoader openObject(WindowCursor curs, AnyObjectId id)
@Deprecated
public ObjectLoader openObject(ObjectReader curs, AnyObjectId id)
throws IOException {
return getObjectDatabase().openObject(curs, id);
try {
return curs.openObject(id);
} catch (MissingObjectException notFound) {
return null;
}
}
/**
* Open object in all packs containing specified object.
*
* @param objectId
* id of object to search for
* @param curs
* temporary working space associated with the calling thread.
* @return collection of loaders for this object, from all packs containing
* this object
* @throws IOException
*/
public abstract Collection<PackedObjectLoader> openObjectInAllPacks(
AnyObjectId objectId, WindowCursor curs)
throws IOException;
/**
* Open object in all packs containing specified object.
*
* @param objectId
* id of object to search for
* @param resultLoaders
* result collection of loaders for this object, filled with
* loaders from all packs containing specified object
* @param curs
* temporary working space associated with the calling thread.
* @throws IOException
*/
abstract void openObjectInAllPacks(final AnyObjectId objectId,
final Collection<PackedObjectLoader> resultLoaders,
final WindowCursor curs) throws IOException;
/**
* @param id
* SHA'1 of a blob

View File

@ -45,11 +45,14 @@
package org.eclipse.jgit.lib;
import java.io.IOException;
import java.util.Collection;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import org.eclipse.jgit.errors.MissingObjectException;
/** Active handle to a ByteWindow. */
public final class WindowCursor {
final class WindowCursor extends ObjectReader {
/** Temporary buffer large enough for at least one raw object id. */
final byte[] tempId = new byte[Constants.OBJECT_ID_LENGTH];
@ -57,6 +60,32 @@ public final class WindowCursor {
private ByteWindow window;
private final FileObjectDatabase db;
WindowCursor(FileObjectDatabase db) {
this.db = db;
}
public boolean hasObject(AnyObjectId objectId) throws IOException {
return db.hasObject(objectId);
}
public ObjectLoader openObject(AnyObjectId objectId, int typeHint)
throws MissingObjectException, IOException {
final ObjectLoader ldr = db.openObject(this, objectId);
if (ldr == null) {
if (typeHint == OBJ_ANY)
throw new MissingObjectException(objectId.copy(), "unknown");
throw new MissingObjectException(objectId.copy(), typeHint);
}
return ldr;
}
void openObjectInAllPacks(AnyObjectId otp,
Collection<PackedObjectLoader> reuseLoaders) throws IOException {
db.openObjectInAllPacks(reuseLoaders, this, otp);
}
/**
* Copy bytes from the window to a caller supplied buffer.
*
@ -168,14 +197,4 @@ public void release() {
inf = null;
}
}
/**
* @param curs cursor to release; may be null.
* @return always null.
*/
public static WindowCursor release(final WindowCursor curs) {
if (curs != null)
curs.release();
return null;
}
}

View File

@ -53,7 +53,7 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTree;
@ -202,7 +202,7 @@ protected AbstractTreeIterator mergeBase(final int aIdx, final int bIdx)
*/
protected AbstractTreeIterator openTree(final AnyObjectId treeId)
throws IncorrectObjectTypeException, IOException {
final WindowCursor curs = new WindowCursor();
final ObjectReader curs = db.newObjectReader();
try {
return new CanonicalTreeParser(null, db, treeId, curs);
} finally {

View File

@ -62,7 +62,7 @@
import org.eclipse.jgit.lib.ObjectIdSubclassMap;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
@ -159,7 +159,7 @@ public class RevWalk implements Iterable<RevCommit> {
final Repository db;
final WindowCursor curs;
final ObjectReader curs;
final MutableObjectId idBuffer;
@ -193,7 +193,7 @@ public class RevWalk implements Iterable<RevCommit> {
*/
public RevWalk(final Repository repo) {
db = repo;
curs = new WindowCursor();
curs = db.newObjectReader();
idBuffer = new MutableObjectId();
objects = new ObjectIdSubclassMap<RevObject>();
roots = new ArrayList<RevCommit>();

View File

@ -79,7 +79,7 @@
import org.eclipse.jgit.lib.PackLock;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.util.NB;
/** Indexes Git pack files for local use. */
@ -213,7 +213,7 @@ public static IndexPack create(final Repository db, final InputStream is)
/** If {@link #fixThin} this is the last byte of the original checksum. */
private long originalEOF;
private WindowCursor readCurs;
private ObjectReader readCurs;
/**
* Create a new pack indexer utility.
@ -232,7 +232,7 @@ public IndexPack(final Repository db, final InputStream src,
objectDatabase = db.getObjectDatabase().newCachedDatabase();
in = src;
inflater = InflaterCache.get();
readCurs = new WindowCursor();
readCurs = objectDatabase.newReader();
buf = new byte[BUFFER_SIZE];
objectData = new byte[BUFFER_SIZE];
objectDigest = Constants.newMessageDigest();
@ -430,7 +430,13 @@ public void index(final ProgressMonitor progress) throws IOException {
inflater = null;
objectDatabase.close();
}
readCurs = WindowCursor.release(readCurs);
try {
if (readCurs != null)
readCurs.release();
} finally {
readCurs = null;
}
progress.endTask();
if (packOut != null)
@ -847,12 +853,16 @@ private void verifySafeObject(final AnyObjectId id, final int type,
}
}
final ObjectLoader ldr = objectDatabase.openObject(readCurs, id);
if (ldr != null) {
try {
final ObjectLoader ldr = readCurs.openObject(id, type);
final byte[] existingData = ldr.getCachedBytes();
if (ldr.getType() != type || !Arrays.equals(data, existingData)) {
throw new IOException(MessageFormat.format(JGitText.get().collisionOn, id.name()));
}
} catch (MissingObjectException notLocal) {
// This is OK, we don't have a copy of the object locally
// but the API throws when we try to read it as usually its
// an error to read something that doesn't exist.
}
}

View File

@ -56,7 +56,7 @@
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
/**
@ -474,7 +474,7 @@ public EmptyTreeIterator createEmptyTreeIterator() {
* a loose object or pack file could not be read.
*/
public AbstractTreeIterator createSubtreeIterator(final Repository repo,
final MutableObjectId idBuffer, final WindowCursor curs)
final MutableObjectId idBuffer, final ObjectReader curs)
throws IncorrectObjectTypeException, IOException {
return createSubtreeIterator(repo);
}

View File

@ -56,7 +56,7 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
/** Parses raw Git trees from the canonical semi-text/semi-binary format. */
public class CanonicalTreeParser extends AbstractTreeIterator {
@ -102,7 +102,7 @@ public CanonicalTreeParser() {
* a loose object or pack file could not be read.
*/
public CanonicalTreeParser(final byte[] prefix, final Repository repo,
final AnyObjectId treeId, final WindowCursor curs)
final AnyObjectId treeId, final ObjectReader curs)
throws IncorrectObjectTypeException, IOException {
super(prefix);
reset(repo, treeId, curs);
@ -148,7 +148,7 @@ public void reset(final byte[] treeData) {
* a loose object or pack file could not be read.
*/
public CanonicalTreeParser resetRoot(final Repository repo,
final AnyObjectId id, final WindowCursor curs)
final AnyObjectId id, final ObjectReader curs)
throws IncorrectObjectTypeException, IOException {
CanonicalTreeParser p = this;
while (p.parent != null)
@ -197,7 +197,7 @@ public CanonicalTreeParser next() {
* a loose object or pack file could not be read.
*/
public void reset(final Repository repo, final AnyObjectId id,
final WindowCursor curs)
final ObjectReader curs)
throws IncorrectObjectTypeException, IOException {
final ObjectLoader ldr = repo.openObject(curs, id);
if (ldr == null) {
@ -214,7 +214,7 @@ public void reset(final Repository repo, final AnyObjectId id,
@Override
public CanonicalTreeParser createSubtreeIterator(final Repository repo,
final MutableObjectId idBuffer, final WindowCursor curs)
final MutableObjectId idBuffer, final ObjectReader curs)
throws IncorrectObjectTypeException, IOException {
idBuffer.fromRaw(idBuffer(), idOffset());
if (!FileMode.TREE.equals(mode)) {
@ -242,7 +242,7 @@ public CanonicalTreeParser createSubtreeIterator(final Repository repo,
* a loose object or pack file could not be read.
*/
public final CanonicalTreeParser createSubtreeIterator0(
final Repository repo, final AnyObjectId id, final WindowCursor curs)
final Repository repo, final AnyObjectId id, final ObjectReader curs)
throws IOException {
final CanonicalTreeParser p = new CanonicalTreeParser(this);
p.reset(repo, id, curs);
@ -251,7 +251,7 @@ public final CanonicalTreeParser createSubtreeIterator0(
public CanonicalTreeParser createSubtreeIterator(final Repository repo)
throws IncorrectObjectTypeException, IOException {
final WindowCursor curs = new WindowCursor();
final ObjectReader curs = repo.newObjectReader();
try {
return createSubtreeIterator(repo, new MutableObjectId(), curs);
} finally {

View File

@ -57,7 +57,7 @@
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.WindowCursor;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
@ -155,7 +155,7 @@ public static TreeWalk forPath(final Repository db, final String path,
private final MutableObjectId idBuffer = new MutableObjectId();
private final WindowCursor curs = new WindowCursor();
private final ObjectReader curs;
private TreeFilter filter;
@ -181,6 +181,7 @@ public static TreeWalk forPath(final Repository db, final String path,
*/
public TreeWalk(final Repository repo) {
db = repo;
curs = repo.newObjectReader();
filter = TreeFilter.ALL;
trees = new AbstractTreeIterator[] { new EmptyTreeIterator() };
}