diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java index f0159f626..a5762b61e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java @@ -213,8 +213,22 @@ long getObjectSize2(WindowCursor curs, String objectName, AnyObjectId objectId) } @Override - boolean insertUnpackedObject(File tmp, ObjectId objectId, boolean force) { - return wrapped.insertUnpackedObject(tmp, objectId, force); + InsertLooseObjectResult insertUnpackedObject(File tmp, ObjectId objectId, + boolean createDuplicate) { + InsertLooseObjectResult result = wrapped.insertUnpackedObject(tmp, + objectId, createDuplicate); + switch (result) { + case INSERTED: + case EXISTS_LOOSE: + if (!unpackedObjects.contains(objectId)) + unpackedObjects.add(objectId); + break; + + case EXISTS_PACKED: + case FAILURE: + break; + } + return result; } @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java index 29c7a2531..8bd375101 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java @@ -57,6 +57,10 @@ import org.eclipse.jgit.storage.pack.PackWriter; abstract class FileObjectDatabase extends ObjectDatabase { + static enum InsertLooseObjectResult { + INSERTED, EXISTS_PACKED, EXISTS_LOOSE, FAILURE; + } + @Override public ObjectReader newReader() { return new WindowCursor(this); @@ -249,7 +253,8 @@ abstract long getObjectSize1(WindowCursor curs, AnyObjectId objectId) abstract long getObjectSize2(WindowCursor curs, String objectName, AnyObjectId objectId) throws IOException; - abstract boolean insertUnpackedObject(File tmp, ObjectId id, boolean force); + abstract InsertLooseObjectResult insertUnpackedObject(File tmp, + ObjectId id, boolean createDuplicate); abstract FileObjectDatabase newCachedFileObjectDatabase(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java index 372a97813..e7ccba082 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java @@ -455,23 +455,33 @@ ObjectLoader openObject2(final WindowCursor curs, } @Override - boolean insertUnpackedObject(File tmp, ObjectId id, boolean force) { - if (!force && has(id)) { - // Object is already in the repository, remove temporary file. - // + InsertLooseObjectResult insertUnpackedObject(File tmp, ObjectId id, + boolean createDuplicate) { + // If the object is already in the repository, remove temporary file. + // + if (unpackedObjectCache.isUnpacked(id)) { tmp.delete(); - return true; + return InsertLooseObjectResult.EXISTS_LOOSE; } + if (!createDuplicate && has(id)) { + tmp.delete(); + return InsertLooseObjectResult.EXISTS_PACKED; + } + tmp.setReadOnly(); final File dst = fileFor(id); - if (force && dst.exists()) { + if (dst.exists()) { + // We want to be extra careful and avoid replacing an object + // that already exists. We can't be sure renameTo() would + // fail on all platforms if dst exists, so we check first. + // tmp.delete(); - return true; + return InsertLooseObjectResult.EXISTS_LOOSE; } if (tmp.renameTo(dst)) { unpackedObjectCache.add(id); - return true; + return InsertLooseObjectResult.INSERTED; } // Maybe the directory doesn't exist yet as the object @@ -481,12 +491,12 @@ boolean insertUnpackedObject(File tmp, ObjectId id, boolean force) { dst.getParentFile().mkdir(); if (tmp.renameTo(dst)) { unpackedObjectCache.add(id); - return true; + return InsertLooseObjectResult.INSERTED; } - if (!force && has(id)) { + if (!createDuplicate && has(id)) { tmp.delete(); - return true; + return InsertLooseObjectResult.EXISTS_PACKED; } // The object failed to be renamed into its proper @@ -495,7 +505,7 @@ boolean insertUnpackedObject(File tmp, ObjectId id, boolean force) { // fail. // tmp.delete(); - return false; + return InsertLooseObjectResult.FAILURE; } boolean tryAgain1() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java index d92285de8..074ebb961 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java @@ -83,9 +83,18 @@ public ObjectId insert(final int type, long len, final InputStream is) final MessageDigest md = digest(); final File tmp = toTemp(md, type, len, is); final ObjectId id = ObjectId.fromRaw(md.digest()); - if (db.insertUnpackedObject(tmp, id, false /* no duplicate */)) + + switch (db.insertUnpackedObject(tmp, id, false /* no duplicate */)) { + case INSERTED: + case EXISTS_PACKED: + case EXISTS_LOOSE: return id; + case FAILURE: + default: + break; + } + final File dst = db.fileFor(id); throw new ObjectWritingException("Unable to create new object: " + dst); }