Change-Id: I01821d6a9fbed7a5fe4619884e42937fbd6909cetags/v4.8.0.201705170830-rc1
@@ -45,7 +45,10 @@ | |||
package org.eclipse.jgit.transport; | |||
import static java.nio.charset.StandardCharsets.UTF_8; | |||
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
import static org.junit.Assert.assertTrue; | |||
import static org.junit.Assert.fail; | |||
@@ -59,10 +62,16 @@ import java.util.Collections; | |||
import java.util.Set; | |||
import org.eclipse.jgit.errors.MissingBundlePrerequisiteException; | |||
import org.eclipse.jgit.errors.MissingObjectException; | |||
import org.eclipse.jgit.errors.NotSupportedException; | |||
import org.eclipse.jgit.errors.TransportException; | |||
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; | |||
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.NullProgressMonitor; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.ObjectInserter; | |||
import org.eclipse.jgit.lib.ObjectReader; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
@@ -161,6 +170,39 @@ public class BundleWriterTest extends SampleDataRepositoryTestCase { | |||
assertTrue(caught); | |||
} | |||
@Test | |||
public void testCustomObjectReader() throws Exception { | |||
String refName = "refs/heads/blob"; | |||
String data = "unflushed data"; | |||
ObjectId id; | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
try (Repository repo = new InMemoryRepository( | |||
new DfsRepositoryDescription("repo")); | |||
ObjectInserter ins = repo.newObjectInserter(); | |||
ObjectReader or = ins.newReader()) { | |||
id = ins.insert(OBJ_BLOB, Constants.encode(data)); | |||
BundleWriter bw = new BundleWriter(or); | |||
bw.include(refName, id); | |||
bw.writeBundle(NullProgressMonitor.INSTANCE, out); | |||
assertNull(repo.exactRef(refName)); | |||
try { | |||
repo.open(id, OBJ_BLOB); | |||
fail("We should not be able to open the unflushed blob"); | |||
} catch (MissingObjectException e) { | |||
// Expected. | |||
} | |||
} | |||
try (Repository repo = new InMemoryRepository( | |||
new DfsRepositoryDescription("copy"))) { | |||
fetchFromBundle(repo, out.toByteArray()); | |||
Ref ref = repo.exactRef(refName); | |||
assertNotNull(ref); | |||
assertEquals(id, ref.getObjectId()); | |||
assertEquals(data, new String(repo.open(id, OBJ_BLOB).getBytes(), UTF_8)); | |||
} | |||
} | |||
private static FetchResult fetchFromBundle(final Repository newRepo, | |||
final byte[] bundle) throws URISyntaxException, | |||
NotSupportedException, TransportException { |
@@ -58,6 +58,7 @@ import org.eclipse.jgit.internal.storage.pack.PackWriter; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.ObjectReader; | |||
import org.eclipse.jgit.lib.ProgressMonitor; | |||
import org.eclipse.jgit.lib.Ref; | |||
import org.eclipse.jgit.lib.Repository; | |||
@@ -84,6 +85,8 @@ import org.eclipse.jgit.storage.pack.PackConfig; | |||
public class BundleWriter { | |||
private final Repository db; | |||
private final ObjectReader reader; | |||
private final Map<String, ObjectId> include; | |||
private final Set<RevCommit> assume; | |||
@@ -100,8 +103,26 @@ public class BundleWriter { | |||
* @param repo | |||
* repository where objects are stored. | |||
*/ | |||
public BundleWriter(final Repository repo) { | |||
public BundleWriter(Repository repo) { | |||
db = repo; | |||
reader = null; | |||
include = new TreeMap<>(); | |||
assume = new HashSet<>(); | |||
tagTargets = new HashSet<>(); | |||
} | |||
/** | |||
* Create a writer for a bundle. | |||
* | |||
* @param or | |||
* reader for reading objects. Will be closed at the end of {@link | |||
* #writeBundle(ProgressMonitor, OutputStream)}, but readers may be | |||
* reused after closing. | |||
* @since 4.8 | |||
*/ | |||
public BundleWriter(ObjectReader or) { | |||
db = null; | |||
reader = or; | |||
include = new TreeMap<>(); | |||
assume = new HashSet<>(); | |||
tagTargets = new HashSet<>(); | |||
@@ -112,7 +133,8 @@ public class BundleWriter { | |||
* | |||
* @param pc | |||
* configuration controlling packing parameters. If null the | |||
* source repository's settings will be used. | |||
* source repository's settings will be used, or the default | |||
* settings if constructed without a repo. | |||
*/ | |||
public void setPackConfig(PackConfig pc) { | |||
this.packConfig = pc; | |||
@@ -196,10 +218,7 @@ public class BundleWriter { | |||
*/ | |||
public void writeBundle(ProgressMonitor monitor, OutputStream os) | |||
throws IOException { | |||
PackConfig pc = packConfig; | |||
if (pc == null) | |||
pc = new PackConfig(db); | |||
try (PackWriter packWriter = new PackWriter(pc, db.newObjectReader())) { | |||
try (PackWriter packWriter = newPackWriter()) { | |||
packWriter.setObjectCountCallback(callback); | |||
final HashSet<ObjectId> inc = new HashSet<>(); | |||
@@ -242,6 +261,14 @@ public class BundleWriter { | |||
} | |||
} | |||
private PackWriter newPackWriter() { | |||
PackConfig pc = packConfig; | |||
if (pc == null) { | |||
pc = db != null ? new PackConfig(db) : new PackConfig(); | |||
} | |||
return new PackWriter(pc, reader != null ? reader : db.newObjectReader()); | |||
} | |||
/** | |||
* Set the {@link ObjectCountCallback}. | |||
* <p> |