[JGIT PATCH v2] Don't keep an empty pack uploaded through receive-pack

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The receive-pack protocol sometimes gets an empty pack file if
there are commands to process but no data was needed to be sent.
In such cases we shouldn't create an empty 32 byte pack on disk,
but instead should discard it.

Since ReceivePack doesn't read the pack header, we only know
the empty state inside of IndexPack.  So we fix it here, to
avoid duplicating the header parsing code into ReceivePack.

Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx>
---

 I missed the test case that assumes we kept an empty pack on disk.
 This version of the patch fixes that test case.

 .../tst/org/spearce/jgit/lib/PackWriterTest.java   |    1 +
 .../src/org/spearce/jgit/transport/IndexPack.java  |   34 ++++++++++++++++---
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java
index 98e0d3a..e828ccc 100644
--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java
@@ -468,6 +468,7 @@ private void verifyOpenPack(final boolean thin) throws IOException {
 		}
 		final InputStream is = new ByteArrayInputStream(os.toByteArray());
 		final IndexPack indexer = new IndexPack(db, is, packBase);
+		indexer.setKeepEmpty(true);
 		indexer.setFixThin(thin);
 		indexer.index(new TextProgressMonitor());
 		pack = new PackFile(db, indexFile, packFile);
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java b/org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java
index 82cd615..bd7bfd0 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/IndexPack.java
@@ -143,6 +143,8 @@ public static IndexPack create(final Repository db, final InputStream is)
 
 	private boolean fixThin;
 
+	private boolean keepEmpty;
+
 	private int outputVersion;
 
 	private final File dstPack;
@@ -239,6 +241,19 @@ public void setFixThin(final boolean fix) {
 	}
 
 	/**
+	 * Configure this index pack instance to keep an empty pack.
+	 * <p>
+	 * By default an empty pack (a pack with no objects) is not kept, as doing
+	 * so is completely pointless. With no objects in the pack there is no data
+	 * stored by it, so the pack is unnecessary.
+	 * 
+	 * @param empty true to enable keeping an empty pack.
+	 */
+	public void setKeepEmpty(final boolean empty) {
+		keepEmpty = empty;
+	}
+
+	/**
 	 * Configure the checker used to validate received objects.
 	 * <p>
 	 * Usually object checking isn't necessary, as Git implementations only
@@ -313,14 +328,14 @@ public void index(final ProgressMonitor progress) throws IOException {
 						fixThinPack(progress);
 					}
 				}
-				if (packOut != null)
+				if (packOut != null && (keepEmpty || entryCount > 0))
 					packOut.getChannel().force(true);
 
 				packDigest = null;
 				baseById = null;
 				baseByPos = null;
 
-				if (dstIdx != null)
+				if (dstIdx != null && (keepEmpty || entryCount > 0))
 					writeIdx();
 
 			} finally {
@@ -336,10 +351,12 @@ public void index(final ProgressMonitor progress) throws IOException {
 					packOut.close();
 			}
 
-			if (dstPack != null)
-				dstPack.setReadOnly();
-			if (dstIdx != null)
-				dstIdx.setReadOnly();
+			if (keepEmpty || entryCount > 0) {
+				if (dstPack != null)
+					dstPack.setReadOnly();
+				if (dstIdx != null)
+					dstIdx.setReadOnly();
+			}
 		} catch (IOException err) {
 			if (dstPack != null)
 				dstPack.delete();
@@ -946,6 +963,11 @@ UnresolvedDelta(final long headerOffset, final int crc32) {
 	 *             removed prior to throwing the exception to the caller.
 	 */
 	public void renameAndOpenPack() throws IOException {
+		if (!keepEmpty && entryCount == 0) {
+			cleanupTemporaryFiles();
+			return;
+		}
+
 		final MessageDigest d = Constants.newMessageDigest();
 		final byte[] oeBytes = new byte[Constants.OBJECT_ID_LENGTH];
 		for (int i = 0; i < entryCount; i++) {
-- 
1.6.2.rc0.173.g5e148

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux