Merge "BundleWriter: Allow constructing from only an ObjectReader"

This commit is contained in:
Jonathan Nieder 2017-04-12 21:12:12 -04:00 committed by Gerrit Code Review @ Eclipse.org
commit e730fcce77
2 changed files with 75 additions and 6 deletions

View File

@ -45,7 +45,10 @@
package org.eclipse.jgit.transport; 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.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@ -59,10 +62,16 @@
import java.util.Set; import java.util.Set;
import org.eclipse.jgit.errors.MissingBundlePrerequisiteException; import org.eclipse.jgit.errors.MissingBundlePrerequisiteException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.NotSupportedException;
import org.eclipse.jgit.errors.TransportException; 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.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId; 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.Ref;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
@ -161,6 +170,39 @@ public void testAbortWrite() throws Exception {
assertTrue(caught); 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, private static FetchResult fetchFromBundle(final Repository newRepo,
final byte[] bundle) throws URISyntaxException, final byte[] bundle) throws URISyntaxException,
NotSupportedException, TransportException { NotSupportedException, TransportException {

View File

@ -58,6 +58,7 @@
import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
@ -84,6 +85,8 @@
public class BundleWriter { public class BundleWriter {
private final Repository db; private final Repository db;
private final ObjectReader reader;
private final Map<String, ObjectId> include; private final Map<String, ObjectId> include;
private final Set<RevCommit> assume; private final Set<RevCommit> assume;
@ -100,8 +103,26 @@ public class BundleWriter {
* @param repo * @param repo
* repository where objects are stored. * repository where objects are stored.
*/ */
public BundleWriter(final Repository repo) { public BundleWriter(Repository repo) {
db = 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<>(); include = new TreeMap<>();
assume = new HashSet<>(); assume = new HashSet<>();
tagTargets = new HashSet<>(); tagTargets = new HashSet<>();
@ -112,7 +133,8 @@ public BundleWriter(final Repository repo) {
* *
* @param pc * @param pc
* configuration controlling packing parameters. If null the * 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) { public void setPackConfig(PackConfig pc) {
this.packConfig = pc; this.packConfig = pc;
@ -196,10 +218,7 @@ public void assume(final RevCommit c) {
*/ */
public void writeBundle(ProgressMonitor monitor, OutputStream os) public void writeBundle(ProgressMonitor monitor, OutputStream os)
throws IOException { throws IOException {
PackConfig pc = packConfig; try (PackWriter packWriter = newPackWriter()) {
if (pc == null)
pc = new PackConfig(db);
try (PackWriter packWriter = new PackWriter(pc, db.newObjectReader())) {
packWriter.setObjectCountCallback(callback); packWriter.setObjectCountCallback(callback);
final HashSet<ObjectId> inc = new HashSet<>(); final HashSet<ObjectId> inc = new HashSet<>();
@ -242,6 +261,14 @@ public void writeBundle(ProgressMonitor monitor, OutputStream os)
} }
} }
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}. * Set the {@link ObjectCountCallback}.
* <p> * <p>