/*
- * Copyright (C) 2008-2009, Google Inc.
+ * Copyright (C) 2008-2010, Google Inc.
* Copyright (C) 2007-2008, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* and other copyright owners as documented in the project's IP log.
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.zip.CRC32;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
private boolean keepEmpty;
+ private boolean needBaseObjectIds;
+
private int outputVersion;
private final File dstPack;
private PackedObjectInfo[] entries;
+ private Set<ObjectId> newObjectIds;
+
private int deltaCount;
private int entryCount;
private ObjectIdSubclassMap<DeltaChain> baseById;
+ private Set<ObjectId> baseIds;
+
private LongMap<UnresolvedDelta> baseByPos;
private byte[] objectData;
keepEmpty = empty;
}
+ /**
+ * Configure this index pack instance to keep track of new objects.
+ * <p>
+ * By default an index pack doesn't save the new objects that were created
+ * when it was instantiated. Setting this flag to {@code true} allows the
+ * caller to use {@link #getNewObjectIds()} to retrieve that list.
+ *
+ * @param b {@code true} to enable keeping track of new objects.
+ */
+ public void setNeedNewObjectIds(boolean b) {
+ if (b)
+ newObjectIds = new HashSet<ObjectId>();
+ else
+ newObjectIds = null;
+ }
+
+ private boolean needNewObjectIds() {
+ return newObjectIds != null;
+ }
+
+ /**
+ * Configure this index pack instance to keep track of the objects assumed
+ * for delta bases.
+ * <p>
+ * By default an index pack doesn't save the objects that were used as delta
+ * bases. Setting this flag to {@code true} will allow the caller to
+ * use {@link #getBaseObjectIds()} to retrieve that list.
+ *
+ * @param b {@code true} to enable keeping track of delta bases.
+ */
+ public void setNeedBaseObjectIds(boolean b) {
+ this.needBaseObjectIds = b;
+ }
+
+ /** @return the new objects that were sent by the user */
+ public Set<ObjectId> getNewObjectIds() {
+ return newObjectIds == null ?
+ Collections.<ObjectId>emptySet() : newObjectIds;
+ }
+
+ /**
+ * @return the set of objects the incoming pack assumed for delta purposes
+ */
+ public Set<ObjectId> getBaseObjectIds() {
+ return baseIds == null ?
+ Collections.<ObjectId>emptySet() : baseIds;
+ }
+
/**
* Configure the checker used to validate received objects.
* <p>
if (packOut == null)
throw new IOException("need packOut");
resolveDeltas(progress);
+ if (needBaseObjectIds) {
+ baseIds = new HashSet<ObjectId>();
+ for (DeltaChain c : baseById) {
+ baseIds.add(c);
+ }
+ }
if (entryCount < objectCount) {
if (!fixThin) {
throw new IOException("pack has "
verifySafeObject(tempObjectId, type, data);
oe = new PackedObjectInfo(pos, crc32, tempObjectId);
- entries[entryCount++] = oe;
+ addObjectAndTrack(oe);
}
resolveChildDeltas(pos, type, data, oe);
verifySafeObject(tempObjectId, type, data);
final int crc32 = (int) crc.getValue();
- entries[entryCount++] = new PackedObjectInfo(pos, crc32, tempObjectId);
+ addObjectAndTrack(new PackedObjectInfo(pos, crc32, tempObjectId));
}
private void verifySafeObject(final AnyObjectId id, final int type,
if (!dstPack.delete())
dstPack.deleteOnExit();
}
-}
+
+ private void addObjectAndTrack(PackedObjectInfo oe) {
+ entries[entryCount++] = oe;
+ if (needNewObjectIds())
+ newObjectIds.add(oe);
+ }
+}
\ No newline at end of file
private PrintWriter msgs;
+ private IndexPack ip;
+
/** The refs we advertised as existing at the start of the connection. */
private Map<String, Ref> refs;
/** Lock around the received pack file, while updating refs. */
private PackLock packLock;
+ private boolean needNewObjectIds;
+
+ private boolean needBaseObjectIds;
+
/**
* Create a new pack receive for an open repository.
*
return refs;
}
+ /**
+ * Configure this receive pack instance to keep track of the objects assumed
+ * for delta bases.
+ * <p>
+ * By default a receive pack doesn't save the objects that were used as
+ * delta bases. Setting this flag to {@code true} will allow the caller to
+ * use {@link #getBaseObjectIds()} to retrieve that list.
+ *
+ * @param b {@code true} to enable keeping track of delta bases.
+ */
+ public void setNeedBaseObjectIds(boolean b) {
+ this.needBaseObjectIds = b;
+ }
+
+ /**
+ * @return the set of objects the incoming pack assumed for delta purposes
+ */
+ public final Set<ObjectId> getBaseObjectIds() {
+ return ip.getBaseObjectIds();
+ }
+
+ /**
+ * Configure this receive pack instance to keep track of new objects.
+ * <p>
+ * By default a receive pack doesn't save the new objects that were created
+ * when it was instantiated. Setting this flag to {@code true} allows the
+ * caller to use {@link #getNewObjectIds()} to retrieve that list.
+ *
+ * @param b {@code true} to enable keeping track of new objects.
+ */
+ public void setNeedNewObjectIds(boolean b) {
+ this.needNewObjectIds = b;
+ }
+
+ /** @return the new objects that were sent by the user */
+ public final Set<ObjectId> getNewObjectIds() {
+ return ip.getNewObjectIds();
+ }
+
/**
* @return true if this class expects a bi-directional pipe opened between
* the client and itself. The default is true.
if (timeoutIn != null)
timeoutIn.setTimeout(10 * timeout * 1000);
- final IndexPack ip = IndexPack.create(db, rawIn);
+ ip = IndexPack.create(db, rawIn);
ip.setFixThin(true);
+ ip.setNeedNewObjectIds(needNewObjectIds);
+ ip.setNeedBaseObjectIds(needBaseObjectIds);
ip.setObjectChecking(isCheckReceivedObjects());
ip.index(NullProgressMonitor.INSTANCE);