diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
index 7c94767b49f8cbb4860ed5e316f4b527c461ede6..23faa42a24a8275d461f82e92670564898832ec9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -54,7 +54,10 @@
 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;
@@ -158,6 +161,8 @@ public static IndexPack create(final Repository db, final InputStream is)
 
 	private boolean keepEmpty;
 
+	private boolean needBaseObjectIds;
+
 	private int outputVersion;
 
 	private final File dstPack;
@@ -168,6 +173,8 @@ public static IndexPack create(final Repository db, final InputStream is)
 
 	private PackedObjectInfo[] entries;
 
+	private Set<ObjectId> newObjectIds;
+
 	private int deltaCount;
 
 	private int entryCount;
@@ -176,6 +183,8 @@ public static IndexPack create(final Repository db, final InputStream is)
 
 	private ObjectIdSubclassMap<DeltaChain> baseById;
 
+	private Set<ObjectId> baseIds;
+
 	private LongMap<UnresolvedDelta> baseByPos;
 
 	private byte[] objectData;
@@ -267,6 +276,54 @@ public void setKeepEmpty(final boolean empty) {
 		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>
@@ -333,6 +390,12 @@ public void index(final ProgressMonitor progress) throws IOException {
 					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 "
@@ -453,7 +516,7 @@ private void resolveDeltas(final long pos, final int oldCRC, int type,
 
 			verifySafeObject(tempObjectId, type, data);
 			oe = new PackedObjectInfo(pos, crc32, tempObjectId);
-			entries[entryCount++] = oe;
+			addObjectAndTrack(oe);
 		}
 
 		resolveChildDeltas(pos, type, data, oe);
@@ -749,7 +812,7 @@ private void whole(final int type, final long pos, final long sz)
 
 		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,
@@ -1112,4 +1175,10 @@ private void cleanupTemporaryFiles() {
 		if (!dstPack.delete())
 			dstPack.deleteOnExit();
 	}
-}
+
+	private void addObjectAndTrack(PackedObjectInfo oe) {
+		entries[entryCount++] = oe;
+		if (needNewObjectIds())
+			newObjectIds.add(oe);
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index 4d63ee68ef5c4f0799b5a740235e421270d693c1..8d75f3cb92cb0e09e7e71e03b0e4f8b81bbd4b66 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -153,6 +153,8 @@ public class ReceivePack {
 
 	private PrintWriter msgs;
 
+	private IndexPack ip;
+
 	/** The refs we advertised as existing at the start of the connection. */
 	private Map<String, Ref> refs;
 
@@ -171,6 +173,10 @@ public class ReceivePack {
 	/** 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.
 	 *
@@ -236,6 +242,45 @@ public final Map<String, Ref> getAdvertisedRefs() {
 		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.
@@ -685,8 +730,10 @@ private void receivePack() throws IOException {
 		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);