{"thread":{"id":"17735","subject":"[JGIT PATCH 3/9] Document why WindowFile's hash is *31","startedAt":"2009-02-12T02:36:50Z","lastAt":"2009-02-12T02:36:59Z","messageCount":10,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":9},"messages":[{"id":"104328","messageId":"1234406219-19547-1-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":null,"subject":"[JGIT PATCH 0/9] Misc. pack code cleanups","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:50Z","receivedAt":"2009-02-12T02:36:50Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"This is a short batch of misc. cleanups related to pack handling.\nI'm trying to work towards making it safer to run \"git gc\" while\nJGit has a repository open.\n\nCurrently:\n\n  - when a new pack is added we don't notice it;\n  - when a previously listed pack is removed, we crash;\n  - if a pack stays but its offsets change, we crash;\n  - objects can go *poof* if they were loose and get packed;\n\nThis series doesn't fix any of these issues, but it cleans\nup the code enough that I can start to consider this more.\n\nThe last patch is perhaps a bit more controversial.  It sets\ncore.packindex to 2 by default, which was done in C Git back\nwhen 1.6.0 shipped.\n\n\nShawn O. Pearce (9):\n  Remove the Repository parameter from PackFile's constructor\n  Remove dead stats code from WindowCache\n  Document why WindowFile's hash is *31\n  Allow PackFile to lazily load its PackIndex on first demand\n  Arrange pack files in recency order to improve quick hits\n  Rename readPackHeader() to be onOpenPack()\n  Validate the pack's footer checksum matches that in the index\n  Remove yet another legacy StGit utility function\n  Make pack.indexversion config option default to version 2\n\n .../src/org/spearce/jgit/pgm/IndexPack.java        |    4 +-\n .../tst/org/spearce/jgit/lib/PackWriterTest.java   |    2 +-\n .../tst/org/spearce/jgit/lib/T0004_PackReader.java |    2 +-\n .../org/spearce/jgit/transport/IndexPackTest.java  |    4 +-\n .../src/org/spearce/jgit/lib/CoreConfig.java       |    3 +-\n .../src/org/spearce/jgit/lib/PackFile.java         |   95 +++++++++++++------\n .../src/org/spearce/jgit/lib/PackIndex.java        |    3 +\n .../src/org/spearce/jgit/lib/PackIndexV1.java      |    3 +\n .../src/org/spearce/jgit/lib/PackIndexV2.java      |    3 +\n .../src/org/spearce/jgit/lib/PackWriter.java       |    1 +\n .../org/spearce/jgit/lib/PackedObjectLoader.java   |    4 +-\n .../src/org/spearce/jgit/lib/Repository.java       |   41 +++------\n .../src/org/spearce/jgit/lib/WindowCache.java      |   31 +------\n .../src/org/spearce/jgit/lib/WindowedFile.java     |    4 +\n 14 files changed, 106 insertions(+), 94 deletions(-)\n"},{"id":"104330","messageId":"1234406219-19547-2-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-1-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 1/9] Remove the Repository parameter from PackFile's constructor","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:51Z","receivedAt":"2009-02-12T02:36:51Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"This is a legacy parameter, from back when the WindowCache was\nper-repository and not per-process.  We no longer need to pass\nit down, so I'm ripping it out.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../tst/org/spearce/jgit/lib/PackWriterTest.java   |    2 +-\n .../tst/org/spearce/jgit/lib/T0004_PackReader.java |    2 +-\n .../org/spearce/jgit/transport/IndexPackTest.java  |    4 ++--\n .../src/org/spearce/jgit/lib/PackFile.java         |    5 +----\n .../src/org/spearce/jgit/lib/Repository.java       |    4 ++--\n 5 files changed, 7 insertions(+), 10 deletions(-)\n\ndiff --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\nindex e828ccc..f7139fc 100644\n--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/PackWriterTest.java\n@@ -471,7 +471,7 @@ private void verifyOpenPack(final boolean thin) throws IOException {\n \t\tindexer.setKeepEmpty(true);\n \t\tindexer.setFixThin(thin);\n \t\tindexer.index(new TextProgressMonitor());\n-\t\tpack = new PackFile(db, indexFile, packFile);\n+\t\tpack = new PackFile(indexFile, packFile);\n \t}\n \n \tprivate void verifyObjectsOrder(final ObjectId objectsOrder[]) {\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0004_PackReader.java b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0004_PackReader.java\nindex 6ffb904..b9e5b49 100644\n--- a/org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0004_PackReader.java\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/lib/T0004_PackReader.java\n@@ -54,7 +54,7 @@ public void test003_lookupCompressedObject() throws IOException {\n \t\tfinal PackedObjectLoader or;\n \n \t\tid = ObjectId.fromString(\"902d5476fa249b7abc9d84c611577a81381f0327\");\n-\t\tpr = new PackFile(db, TEST_IDX, TEST_PACK);\n+\t\tpr = new PackFile(TEST_IDX, TEST_PACK);\n \t\tor = pr.get(new WindowCursor(), id);\n \t\tassertNotNull(or);\n \t\tassertEquals(Constants.OBJ_TREE, or.getType());\ndiff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/IndexPackTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/IndexPackTest.java\nindex 46bd969..0c6e678 100644\n--- a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/IndexPackTest.java\n+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/IndexPackTest.java\n@@ -68,7 +68,7 @@ public void test1() throws  IOException {\n \t\ttry {\n \t\t\tIndexPack pack = new IndexPack(db, is, new File(trash, \"tmp_pack1\"));\n \t\t\tpack.index(new TextProgressMonitor());\n-\t\t\tPackFile file = new PackFile(db, new File(trash, \"tmp_pack1.idx\"), new File(trash, \"tmp_pack1.pack\"));\n+\t\t\tPackFile file = new PackFile(new File(trash, \"tmp_pack1.idx\"), new File(trash, \"tmp_pack1.pack\"));\n \t\t\tassertTrue(file.hasObject(ObjectId.fromString(\"4b825dc642cb6eb9a060e54bf8d69288fbee4904\")));\n \t\t\tassertTrue(file.hasObject(ObjectId.fromString(\"540a36d136cf413e4b064c2b0e0a4db60f77feab\")));\n \t\t\tassertTrue(file.hasObject(ObjectId.fromString(\"5b6e7c66c276e7610d4a73c70ec1a1f7c1003259\")));\n@@ -94,7 +94,7 @@ public void test2() throws  IOException {\n \t\ttry {\n \t\t\tIndexPack pack = new IndexPack(db, is, new File(trash, \"tmp_pack2\"));\n \t\t\tpack.index(new TextProgressMonitor());\n-\t\t\tPackFile file = new PackFile(db, new File(trash, \"tmp_pack2.idx\"), new File(trash, \"tmp_pack2.pack\"));\n+\t\t\tPackFile file = new PackFile(new File(trash, \"tmp_pack2.idx\"), new File(trash, \"tmp_pack2.pack\"));\n \t\t\tassertTrue(file.hasObject(ObjectId.fromString(\"02ba32d3649e510002c21651936b7077aa75ffa9\")));\n \t\t\tassertTrue(file.hasObject(ObjectId.fromString(\"0966a434eb1a025db6b71485ab63a3bfbea520b6\")));\n \t\t\tassertTrue(file.hasObject(ObjectId.fromString(\"09efc7e59a839528ac7bda9fa020dc9101278680\")));\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\nindex 0de4c55..8368827 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n@@ -65,8 +65,6 @@\n \t/**\n \t * Construct a reader for an existing, pre-indexed packfile.\n \t * \n-\t * @param parentRepo\n-\t *            Git repository holding this pack file\n \t * @param idxFile\n \t *            path of the <code>.idx</code> file listing the contents.\n \t * @param packFile\n@@ -74,8 +72,7 @@\n \t * @throws IOException\n \t *             the index file cannot be accessed at this time.\n \t */\n-\tpublic PackFile(final Repository parentRepo, final File idxFile,\n-\t\t\tfinal File packFile) throws IOException {\n+\tpublic PackFile(final File idxFile, final File packFile) throws IOException {\n \t\tpack = new WindowedFile(packFile) {\n \t\t\t@Override\n \t\t\tprotected void onOpen() throws IOException {\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\nindex 8d35f82..963b6e0 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n@@ -800,7 +800,7 @@ synchronized (this) {\n \t\t\tfinal PackFile[] cur = packFileList;\n \t\t\tfinal PackFile[] arr = new PackFile[cur.length + 1];\n \t\t\tSystem.arraycopy(cur, 0, arr, 1, cur.length);\n-\t\t\tarr[0] = new PackFile(this, idx, pack);\n+\t\t\tarr[0] = new PackFile(idx, pack);\n \t\t\tpackFileList = arr;\n \t\t}\n \t}\n@@ -849,7 +849,7 @@ public boolean accept(final File baseDir, final String n) {\n \t\t\t\t}\n \n \t\t\t\ttry {\n-\t\t\t\t\tpackList.add(new PackFile(this, idxFile, packFile));\n+\t\t\t\t\tpackList.add(new PackFile(idxFile, packFile));\n \t\t\t\t} catch (IOException ioe) {\n \t\t\t\t\t// Whoops. That's not a pack!\n \t\t\t\t\t//\n-- \n1.6.2.rc0.204.gf6b427\n"},{"id":"104336","messageId":"1234406219-19547-3-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-2-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 2/9] Remove dead stats code from WindowCache","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:52Z","receivedAt":"2009-02-12T02:36:52Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"I used this code to try and tune the WindowCache a bit, but we're\nabout as good as we can do for now.  There's no point in keeping\nit all around in somewhat critical paths if we never use it.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/lib/WindowCache.java      |   28 --------------------\n 1 files changed, 0 insertions(+), 28 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java\nindex 0077f52..600ebdf 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java\n@@ -76,14 +76,6 @@ private static final int bits(int newSize) {\n \n \tprivate static int openByteCount;\n \n-\tprivate static int hits;\n-\n-\tprivate static int reqs;\n-\n-\tprivate static int opens;\n-\n-\tprivate static int closes;\n-\n \tstatic {\n \t\tmaxByteCount = 10 * MB;\n \t\twindowSizeShift = bits(8 * KB);\n@@ -93,22 +85,6 @@ private static final int bits(int newSize) {\n \t\tclearedWindowQueue = new ReferenceQueue<Object>();\n \t}\n \n-\tstatic synchronized String statString() {\n-\t\tint maxChain = 0, tot = 0;\n-\t\tfor (ByteWindow<?> e : cache) {\n-\t\t\tint n = 0;\n-\t\t\tfor (; e != null; e = e.chainNext) {\n-\t\t\t\tn++;\n-\t\t\t\ttot++;\n-\t\t\t}\n-\t\t\tmaxChain = Math.max(maxChain, n);\n-\t\t}\n-\t\treturn \"WindowCache[ hits: \" + (hits * 100 / reqs) + \"%\"\n-\t\t\t\t+ \"; windows: \" + tot + \" maxChain: \" + maxChain + \"; kb:\"\n-\t\t\t\t+ (openByteCount / KB) + \"; cache: \" + cache.length + \" fds: \"\n-\t\t\t\t+ (opens - closes) + \",\" + opens + \",\" + closes + \" ]\";\n-\t}\n-\n \tprivate static int cacheTableSize() {\n \t\treturn 5 * (maxByteCount / windowSize) / 2;\n \t}\n@@ -215,7 +191,6 @@ private static synchronized void reconfigureImpl(final int packedGitLimit,\n \t */\n \tpublic static synchronized final void get(final WindowCursor curs,\n \t\t\tfinal WindowedFile wp, final long position) throws IOException {\n-\t\treqs++;\n \t\tfinal int id = (int) (position >> windowSizeShift);\n \t\tfinal int idx = hash(wp, id);\n \t\tfor (ByteWindow<?> e = cache[idx]; e != null; e = e.chainNext) {\n@@ -223,7 +198,6 @@ public static synchronized final void get(final WindowCursor curs,\n \t\t\t\tif ((curs.handle = e.get()) != null) {\n \t\t\t\t\tcurs.window = e;\n \t\t\t\t\tmakeMostRecent(e);\n-\t\t\t\t\thits++;\n \t\t\t\t\treturn;\n \t\t\t\t}\n \n@@ -234,7 +208,6 @@ public static synchronized final void get(final WindowCursor curs,\n \n \t\tif (wp.openCount == 0) {\n \t\t\ttry {\n-\t\t\t\topens++;\n \t\t\t\twp.openCount = 1;\n \t\t\t\twp.cacheOpen();\n \t\t\t} catch (IOException ioe) {\n@@ -340,7 +313,6 @@ private static void clear(final ByteWindow<?> e) {\n \tprivate static void unlinkSize(final ByteWindow<?> e) {\n \t\tif (e.sizeActive) {\n \t\t\tif (--e.provider.openCount == 0) {\n-\t\t\t\tcloses++;\n \t\t\t\te.provider.cacheClose();\n \t\t\t}\n \t\t\topenByteCount -= e.size;\n-- \n1.6.2.rc0.204.gf6b427\n"},{"id":"104327","messageId":"1234406219-19547-4-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-3-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 3/9] Document why WindowFile's hash is *31","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:53Z","receivedAt":"2009-02-12T02:36:53Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"It doesn't really make sense on its own, but if you know about\nthe assumption in WindowCache.hash() it all becomes a bit more\nclear to the reader.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/lib/WindowCache.java      |    3 +++\n .../src/org/spearce/jgit/lib/WindowedFile.java     |    4 ++++\n 2 files changed, 7 insertions(+), 0 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java\nindex 600ebdf..0b9d20c 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowCache.java\n@@ -362,6 +362,9 @@ private static void insertLRU(final ByteWindow<?> e) {\n \t}\n \n \tprivate static int hash(final WindowedFile wp, final int id) {\n+\t\t// wp.hash was already \"stirred up\" a bit by * 31 when\n+\t\t// it was created. Its reasonable to just add here.\n+\t\t//\n \t\treturn ((wp.hash + id) >>> 1) % cache.length;\n \t}\n \ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java\nindex 5eb8465..db8ea88 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/WindowedFile.java\n@@ -88,6 +88,10 @@\n \t */\n \tpublic WindowedFile(final File file) {\n \t\tfPath = file;\n+\n+\t\t// Multiply by 31 here so we can more directly combine with another\n+\t\t// value in WindowCache.hash(), without doing the multiply there.\n+\t\t//\n \t\thash = System.identityHashCode(this) * 31;\n \t\tlength = Long.MAX_VALUE;\n \t}\n-- \n1.6.2.rc0.204.gf6b427\n"},{"id":"104331","messageId":"1234406219-19547-5-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-4-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 4/9] Allow PackFile to lazily load its PackIndex on first demand","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:54Z","receivedAt":"2009-02-12T02:36:54Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Repositories which contain several pack files may have a very large\nhistorical pack holding the bulk of the project data, and a much\nsmaller more recent pack holding current data.  In such cases we\nmay be able to answer queries entirely by reading the recent pack\nindex, and never reading the larger historical index.  Since JGit\nreads the entire index into memory, avoiding reading the larger\nindex can save some time on short uses of a Repository.\n\nThis change only sets up the lazy loading of the index.  Because\nthe packs aren't sorted by newest-to-oldest in Repository we are\nstill very likely to demand load packs we didn't need to examine.\n\nThis change also opens the door for potentially releasing one or\nmore PackIndex objects when memory gets low, but doesn't actually\nimplement any sort of soft reference semantics.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/lib/PackFile.java         |   67 +++++++++++++-------\n .../org/spearce/jgit/lib/PackedObjectLoader.java   |    4 +-\n .../src/org/spearce/jgit/lib/Repository.java       |   19 +++---\n 3 files changed, 56 insertions(+), 34 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\nindex 8368827..3542560 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n@@ -42,6 +42,7 @@\n import java.io.File;\n import java.io.IOException;\n import java.io.OutputStream;\n+import java.util.Collections;\n import java.util.Iterator;\n import java.util.zip.CRC32;\n import java.util.zip.CheckedOutputStream;\n@@ -56,9 +57,11 @@\n  * objects are similar.\n  */\n public class PackFile implements Iterable<PackIndex.MutableEntry> {\n+\tprivate final File idxFile;\n+\n \tprivate final WindowedFile pack;\n \n-\tprivate final PackIndex idx;\n+\tprivate PackIndex loadedIdx;\n \n \tprivate PackReverseIndex reverseIdx;\n \n@@ -69,21 +72,22 @@\n \t *            path of the <code>.idx</code> file listing the contents.\n \t * @param packFile\n \t *            path of the <code>.pack</code> file holding the data.\n-\t * @throws IOException\n-\t *             the index file cannot be accessed at this time.\n \t */\n-\tpublic PackFile(final File idxFile, final File packFile) throws IOException {\n+\tpublic PackFile(final File idxFile, final File packFile) {\n+\t\tthis.idxFile = idxFile;\n \t\tpack = new WindowedFile(packFile) {\n \t\t\t@Override\n \t\t\tprotected void onOpen() throws IOException {\n \t\t\t\treadPackHeader();\n \t\t\t}\n \t\t};\n-\t\ttry {\n-\t\t\tidx = PackIndex.open(idxFile);\n-\t\t} catch (IOException ioe) {\n-\t\t\tthrow ioe;\n+\t}\n+\n+\tprivate synchronized PackIndex idx() throws IOException {\n+\t\tif (loadedIdx == null) {\n+\t\t\tloadedIdx = PackIndex.open(idxFile);\n \t\t}\n+\t\treturn loadedIdx;\n \t}\n \n \tfinal PackedObjectLoader resolveBase(final WindowCursor curs, final long ofs)\n@@ -106,9 +110,11 @@ public File getPackFile() {\n \t * @param id\n \t *            the object to look for. Must not be null.\n \t * @return true if the object is in this pack; false otherwise.\n+\t * @throws IOException\n+\t *             the index file cannot be loaded into memory.\n \t */\n-\tpublic boolean hasObject(final AnyObjectId id) {\n-\t\treturn idx.hasObject(id);\n+\tpublic boolean hasObject(final AnyObjectId id) throws IOException {\n+\t\treturn idx().hasObject(id);\n \t}\n \n \t/**\n@@ -125,7 +131,7 @@ public boolean hasObject(final AnyObjectId id) {\n \t */\n \tpublic PackedObjectLoader get(final WindowCursor curs, final AnyObjectId id)\n \t\t\tthrows IOException {\n-\t\tfinal long offset = idx.findOffset(id);\n+\t\tfinal long offset = idx().findOffset(id);\n \t\treturn 0 < offset ? reader(curs, offset) : null;\n \t}\n \n@@ -135,6 +141,9 @@ public PackedObjectLoader get(final WindowCursor curs, final AnyObjectId id)\n \tpublic void close() {\n \t\tUnpackedObjectCache.purge(pack);\n \t\tpack.close();\n+\t\tsynchronized (this) {\n+\t\t\tloadedIdx = null;\n+\t\t}\n \t}\n \n \t/**\n@@ -150,7 +159,11 @@ public void close() {\n \t * @see PackIndex#iterator()\n \t */\n \tpublic Iterator<PackIndex.MutableEntry> iterator() {\n-\t\treturn idx.iterator();\n+\t\ttry {\n+\t\t\treturn idx().iterator();\n+\t\t} catch (IOException e) {\n+\t\t\treturn Collections.<PackIndex.MutableEntry> emptyList().iterator();\n+\t\t}\n \t}\n \n \t/**\n@@ -158,9 +171,11 @@ public void close() {\n \t * relies on pack index, giving number of effectively available objects.\n \t * \n \t * @return number of objects in index of this pack, likewise in this pack\n+\t * @throws IOException\n+\t *             the index file cannot be loaded into memory.\n \t */\n-\tlong getObjectCount() {\n-\t\treturn idx.getObjectCount();\n+\tlong getObjectCount() throws IOException {\n+\t\treturn idx().getObjectCount();\n \t}\n \n \t/**\n@@ -170,8 +185,10 @@ long getObjectCount() {\n \t * @param offset\n \t *            start offset of object to find\n \t * @return object id for this offset, or null if no object was found\n+\t * @throws IOException\n+\t *             the index file cannot be loaded into memory.\n \t */\n-\tObjectId findObjectForOffset(final long offset) {\n+\tObjectId findObjectForOffset(final long offset) throws IOException {\n \t\treturn getReverseIdx().findObject(offset);\n \t}\n \n@@ -196,6 +213,7 @@ final void copyRawData(final PackedObjectLoader loader,\n \t\tfinal long dataOffset = loader.dataOffset;\n \t\tfinal int cnt = (int) (findEndOffset(objectOffset) - dataOffset);\n \t\tfinal WindowCursor curs = loader.curs;\n+\t\tfinal PackIndex idx = idx();\n \n \t\tif (idx.hasCRC32Support()) {\n \t\t\tfinal CRC32 crc = new CRC32();\n@@ -231,8 +249,8 @@ final void copyRawData(final PackedObjectLoader loader,\n \t\t}\n \t}\n \n-\tboolean supportsFastCopyRawData() {\n-\t\treturn idx.hasCRC32Support();\n+\tboolean supportsFastCopyRawData() throws IOException {\n+\t\treturn idx().hasCRC32Support();\n \t}\n \n \n@@ -258,11 +276,12 @@ private void readPackHeader() throws IOException {\n \t\tposition += 4;\n \n \t\tpack.readFully(position, intbuf, curs);\n-\t\tfinal long objectCnt = NB.decodeUInt32(intbuf, 0);\n-\t\tif (idx.getObjectCount() != objectCnt)\n+\t\tfinal long packCnt = NB.decodeUInt32(intbuf, 0);\n+\t\tfinal long idxCnt = idx().getObjectCount();\n+\t\tif (idxCnt != packCnt)\n \t\t\tthrow new IOException(\"Pack index\"\n-\t\t\t\t\t+ \" object count mismatch; expected \" + objectCnt\n-\t\t\t\t\t+ \" found \" + idx.getObjectCount() + \": \" + pack.getName());\n+\t\t\t\t\t+ \" object count mismatch; expected \" + packCnt\n+\t\t\t\t\t+ \" found \" + idxCnt + \": \" + pack.getName());\n \t}\n \n \tprivate PackedObjectLoader reader(final WindowCursor curs,\n@@ -315,14 +334,14 @@ private PackedObjectLoader reader(final WindowCursor curs,\n \t}\n \n \tprivate long findEndOffset(final long startOffset)\n-\t\t\tthrows CorruptObjectException {\n+\t\t\tthrows IOException, CorruptObjectException {\n \t\tfinal long maxOffset = pack.length() - Constants.OBJECT_ID_LENGTH;\n \t\treturn getReverseIdx().findNextOffset(startOffset, maxOffset);\n \t}\n \n-\tprivate synchronized PackReverseIndex getReverseIdx() {\n+\tprivate synchronized PackReverseIndex getReverseIdx() throws IOException {\n \t\tif (reverseIdx == null)\n-\t\t\treverseIdx = new PackReverseIndex(idx);\n+\t\t\treverseIdx = new PackReverseIndex(idx());\n \t\treturn reverseIdx;\n \t}\n }\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackedObjectLoader.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackedObjectLoader.java\nindex 35983fe..56985c1 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackedObjectLoader.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackedObjectLoader.java\n@@ -103,8 +103,10 @@ public void copyRawData(OutputStream out, byte buf[]) throws IOException {\n \t * @return true if this loader is capable of fast raw-data copying basing on\n \t *         compressed data checksum; false if raw-data copying needs\n \t *         uncompressing and compressing data\n+\t * @throws IOException\n+\t *             the index file format cannot be determined.\n \t */\n-\tpublic boolean supportsFastCopyRawData() {\n+\tpublic boolean supportsFastCopyRawData() throws IOException {\n \t\treturn pack.supportsFastCopyRawData();\n \t}\n \ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\nindex 963b6e0..b9c7b2e 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n@@ -248,8 +248,15 @@ public boolean hasObject(final AnyObjectId objectId) {\n \t\tfinal PackFile[] packs = packs();\n \t\tint k = packs.length;\n \t\twhile (k > 0) {\n-\t\t\tif (packs[--k].hasObject(objectId))\n-\t\t\t\treturn true;\n+\t\t\ttry {\n+\t\t\t\tif (packs[--k].hasObject(objectId))\n+\t\t\t\t\treturn true;\n+\t\t\t} catch (IOException e) {\n+\t\t\t\t// Assume that means the pack is invalid, and such\n+\t\t\t\t// packs are treated as though they are empty.\n+\t\t\t\t//\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t}\n \t\treturn toFile(objectId).isFile();\n \t}\n@@ -848,13 +855,7 @@ public boolean accept(final File baseDir, final String n) {\n \t\t\t\t\t\tcontinue SCAN;\n \t\t\t\t}\n \n-\t\t\t\ttry {\n-\t\t\t\t\tpackList.add(new PackFile(idxFile, packFile));\n-\t\t\t\t} catch (IOException ioe) {\n-\t\t\t\t\t// Whoops. That's not a pack!\n-\t\t\t\t\t//\n-\t\t\t\t\tioe.printStackTrace();\n-\t\t\t\t}\n+\t\t\t\tpackList.add(new PackFile(idxFile, packFile));\n \t\t\t}\n \t\t}\n \t}\n-- \n1.6.2.rc0.204.gf6b427\n"},{"id":"104329","messageId":"1234406219-19547-6-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-5-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 5/9] Arrange pack files in recency order to improve quick hits","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:55Z","receivedAt":"2009-02-12T02:36:55Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Packs with newer modification dates are more likely to contain data\nrelated to recent commits, and thus will have a better probability\nof containing an object we care about when we are looking only at\nrecent history.\n\nIn some cases, this may permit JGit to avoid reading a very large\nhistorical pack's index file into memory if the only data we ever\nneed is available in newer pack files.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/lib/PackFile.java         |   11 +++++++++++\n .../src/org/spearce/jgit/lib/Repository.java       |    1 +\n 2 files changed, 12 insertions(+), 0 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\nindex 3542560..7a16bf7 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n@@ -43,6 +43,7 @@\n import java.io.IOException;\n import java.io.OutputStream;\n import java.util.Collections;\n+import java.util.Comparator;\n import java.util.Iterator;\n import java.util.zip.CRC32;\n import java.util.zip.CheckedOutputStream;\n@@ -57,10 +58,19 @@\n  * objects are similar.\n  */\n public class PackFile implements Iterable<PackIndex.MutableEntry> {\n+\t/** Sorts PackFiles to be most recently created to least recently created. */\n+\tpublic static Comparator<PackFile> SORT = new Comparator<PackFile>() {\n+\t\tpublic int compare(final PackFile a, final PackFile b) {\n+\t\t\treturn b.packLastModified - a.packLastModified;\n+\t\t}\n+\t};\n+\n \tprivate final File idxFile;\n \n \tprivate final WindowedFile pack;\n \n+\tprivate int packLastModified;\n+\n \tprivate PackIndex loadedIdx;\n \n \tprivate PackReverseIndex reverseIdx;\n@@ -75,6 +85,7 @@\n \t */\n \tpublic PackFile(final File idxFile, final File packFile) {\n \t\tthis.idxFile = idxFile;\n+\t\tthis.packLastModified = (int) (packFile.lastModified() >> 10);\n \t\tpack = new WindowedFile(packFile) {\n \t\t\t@Override\n \t\t\tprotected void onOpen() throws IOException {\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\nindex b9c7b2e..96c62df 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n@@ -823,6 +823,7 @@ public void scanForPacks() {\n \t\t\tscanForPacks(new File(d, \"pack\"), p);\n \t\tfinal PackFile[] arr = new PackFile[p.size()];\n \t\tp.toArray(arr);\n+\t\tArrays.sort(arr, PackFile.SORT);\n \t\tsynchronized (this) {\n \t\t\tpackFileList = arr;\n \t\t}\n-- \n1.6.2.rc0.204.gf6b427\n"},{"id":"104332","messageId":"1234406219-19547-7-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-6-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 6/9] Rename readPackHeader() to be onOpenPack()","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:56Z","receivedAt":"2009-02-12T02:36:56Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Its just a better name of the function.  Any logic we might try\nto perform to validate the pack file as we open it up to read\nshould be here, and that logic may eventually include validation\nof the footer checksum against the index's footer data.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/lib/PackFile.java         |    5 ++---\n 1 files changed, 2 insertions(+), 3 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\nindex 7a16bf7..d34df03 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n@@ -89,7 +89,7 @@ public PackFile(final File idxFile, final File packFile) {\n \t\tpack = new WindowedFile(packFile) {\n \t\t\t@Override\n \t\t\tprotected void onOpen() throws IOException {\n-\t\t\t\treadPackHeader();\n+\t\t\t\tonOpenPack();\n \t\t\t}\n \t\t};\n \t}\n@@ -264,8 +264,7 @@ boolean supportsFastCopyRawData() throws IOException {\n \t\treturn idx().hasCRC32Support();\n \t}\n \n-\n-\tprivate void readPackHeader() throws IOException {\n+\tprivate void onOpenPack() throws IOException {\n \t\tfinal WindowCursor curs = new WindowCursor();\n \t\tlong position = 0;\n \t\tfinal byte[] sig = new byte[Constants.PACK_SIGNATURE.length];\n-- \n1.6.2.rc0.204.gf6b427\n"},{"id":"104333","messageId":"1234406219-19547-8-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-7-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 7/9] Validate the pack's footer checksum matches that in the index","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:57Z","receivedAt":"2009-02-12T02:36:57Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If the SHA-1 checksum of the entire pack content does not match the\nchecksum stored in the corresponding *.idx file we cannot use the\nindex, as the offsets recorded with it are most likely incorrect.\n\nThis situation can arise if another application repacks the pack\nwith different compression settings, but puts the same set of\nobjects into it.  The offsets are going to be different, but the\nresulting pack file and index file names will be the same.  If we\nhad previously read the old index into memory, but the pack isn't\na match anymore, we can't safely access this pack.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/lib/PackFile.java         |   11 ++++++++++-\n .../src/org/spearce/jgit/lib/PackIndex.java        |    3 +++\n .../src/org/spearce/jgit/lib/PackIndexV1.java      |    3 +++\n .../src/org/spearce/jgit/lib/PackIndexV2.java      |    3 +++\n 4 files changed, 19 insertions(+), 1 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\nindex d34df03..1ee0ad7 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackFile.java\n@@ -42,6 +42,7 @@\n import java.io.File;\n import java.io.IOException;\n import java.io.OutputStream;\n+import java.util.Arrays;\n import java.util.Collections;\n import java.util.Comparator;\n import java.util.Iterator;\n@@ -265,6 +266,7 @@ boolean supportsFastCopyRawData() throws IOException {\n \t}\n \n \tprivate void onOpenPack() throws IOException {\n+\t\tfinal PackIndex idx = idx();\n \t\tfinal WindowCursor curs = new WindowCursor();\n \t\tlong position = 0;\n \t\tfinal byte[] sig = new byte[Constants.PACK_SIGNATURE.length];\n@@ -287,11 +289,18 @@ private void onOpenPack() throws IOException {\n \n \t\tpack.readFully(position, intbuf, curs);\n \t\tfinal long packCnt = NB.decodeUInt32(intbuf, 0);\n-\t\tfinal long idxCnt = idx().getObjectCount();\n+\t\tfinal long idxCnt = idx.getObjectCount();\n \t\tif (idxCnt != packCnt)\n \t\t\tthrow new IOException(\"Pack index\"\n \t\t\t\t\t+ \" object count mismatch; expected \" + packCnt\n \t\t\t\t\t+ \" found \" + idxCnt + \": \" + pack.getName());\n+\t\t\n+\t\tfinal byte[] csumbuf = new byte[20];\n+\t\tpack.readFully(pack.length() - 20, csumbuf, curs);\n+\t\tif (!Arrays.equals(csumbuf, idx.packChecksum))\n+\t\t\tthrow new IOException(\"Pack index mismatch; pack SHA-1 is \"\n+\t\t\t\t\t+ ObjectId.fromRaw(csumbuf).name() + \", index expects \"\n+\t\t\t\t\t+ ObjectId.fromRaw(idx.packChecksum).name());\n \t}\n \n \tprivate PackedObjectLoader reader(final WindowCursor curs,\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndex.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndex.java\nindex 13acbd1..473ce1e 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndex.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndex.java\n@@ -112,6 +112,9 @@ private static boolean isTOC(final byte[] h) {\n \t\treturn true;\n \t}\n \n+\t/** Footer checksum applied on the bottom of the pack file. */\n+\tprotected byte[] packChecksum;\n+\n \t/**\n \t * Determine if an object is contained within the pack file.\n \t * \ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV1.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV1.java\nindex 90b5f6f..fdaa094 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV1.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV1.java\n@@ -79,6 +79,9 @@ PackIndexV1(final InputStream fd, final byte[] hdr)\n \t\t\t}\n \t\t}\n \t\tobjectCnt = idxHeader[255];\n+\n+\t\tpackChecksum = new byte[20];\n+\t\tNB.readFully(fd, packChecksum, 0, packChecksum.length);\n \t}\n \n \tlong getObjectCount() {\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV2.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV2.java\nindex 48a5206..eb56ed9 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV2.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackIndexV2.java\n@@ -142,6 +142,9 @@ PackIndexV2(final InputStream fd) throws IOException {\n \t\t} else {\n \t\t\toffset64 = NO_BYTES;\n \t\t}\n+\n+\t\tpackChecksum = new byte[20];\n+\t\tNB.readFully(fd, packChecksum, 0, packChecksum.length);\n \t}\n \n \t@Override\n-- \n1.6.2.rc0.204.gf6b427\n"},{"id":"104334","messageId":"1234406219-19547-9-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-8-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 8/9] Remove yet another legacy StGit utility function","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:58Z","receivedAt":"2009-02-12T02:36:58Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"We have long since ripped out any StGit support from JGit or EGit.\nThere is no current caller for this function, and it should have\nbeen removed much sooner.  Take it out now anyway.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/lib/Repository.java       |   19 -------------------\n 1 files changed, 0 insertions(+), 19 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\nindex 96c62df..30bd4a3 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Repository.java\n@@ -878,25 +878,6 @@ public String toString() {\n \t}\n \n \t/**\n-\t * @return name of topmost Stacked Git patch.\n-\t * @throws IOException\n-\t */\n-\tpublic String getPatch() throws IOException {\n-\t\tfinal File ptr = new File(getDirectory(),\"patches/\"+getBranch()+\"/applied\");\n-\t\tfinal BufferedReader br = new BufferedReader(new FileReader(ptr));\n-\t\tString last=null;\n-\t\ttry {\n-\t\t\tString line;\n-\t\t\twhile ((line=br.readLine())!=null) {\n-\t\t\t\tlast = line;\n-\t\t\t}\n-\t\t} finally {\n-\t\t\tbr.close();\n-\t\t}\n-\t\treturn last;\n-\t}\n-\n-\t/**\n \t * @return name of current branch\n \t * @throws IOException\n \t */\n-- \n1.6.2.rc0.204.gf6b427\n"},{"id":"104335","messageId":"1234406219-19547-10-git-send-email-spearce@spearce.org","threadId":"17735","inReplyTo":"1234406219-19547-9-git-send-email-spearce@spearce.org","subject":"[JGIT PATCH 9/9] Make pack.indexversion config option default to version 2","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-02-12T02:36:59Z","receivedAt":"2009-02-12T02:36:59Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Git 1.6.0 (released Sun Aug 17 11:42:22 2008 -0700) defaults\nto creating the much safer pack index version 2 format when\nwriting a pack to disk.  Most clients trying to use Git will\nbe running a recent version of C Git alongside JGit so it is\nreasonably safe to assume they have index version 2 reading\nsupport, and are thus prepared to accept this change in the\ndefault output format.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .../src/org/spearce/jgit/pgm/IndexPack.java        |    4 +++-\n .../src/org/spearce/jgit/lib/CoreConfig.java       |    3 ++-\n .../src/org/spearce/jgit/lib/PackWriter.java       |    1 +\n 3 files changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/IndexPack.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/IndexPack.java\nindex 5eacaa4..22803a4 100644\n--- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/IndexPack.java\n+++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/IndexPack.java\n@@ -49,13 +49,15 @@\n \tprivate boolean fixThin;\n \n \t@Option(name = \"--index-version\", usage = \"index file format to create\")\n-\tprivate int indexVersion;\n+\tprivate int indexVersion = -1;\n \n \t@Argument(index = 0, required = true, metaVar = \"base\")\n \tprivate File base;\n \n \t@Override\n \tprotected void run() throws Exception {\n+\t\tif (indexVersion == -1)\n+\t\t\tindexVersion = db.getConfig().getCore().getPackIndexVersion();\n \t\tfinal BufferedInputStream in;\n \t\tfinal org.spearce.jgit.transport.IndexPack ip;\n \t\tin = new BufferedInputStream(System.in);\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/CoreConfig.java b/org.spearce.jgit/src/org/spearce/jgit/lib/CoreConfig.java\nindex 2dd8aea..e98e0bc 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/CoreConfig.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/CoreConfig.java\n@@ -45,6 +45,7 @@\n  */\n public class CoreConfig {\n \tprivate static final int DEFAULT_COMPRESSION = Deflater.DEFAULT_COMPRESSION;\n+\tprivate static final int DEFAULT_INDEXVERSION = 2;\n \n \tprivate final int compression;\n \n@@ -52,7 +53,7 @@\n \n \tCoreConfig(final RepositoryConfig rc) {\n \t\tcompression = rc.getInt(\"core\", \"compression\", DEFAULT_COMPRESSION);\n-\t\tpackIndexVersion = rc.getInt(\"pack\", \"indexversion\", 0);\n+\t\tpackIndexVersion = rc.getInt(\"pack\", \"indexversion\", DEFAULT_INDEXVERSION);\n \t}\n \n \t/**\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/PackWriter.java b/org.spearce.jgit/src/org/spearce/jgit/lib/PackWriter.java\nindex cba2ee7..f9945c4 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/PackWriter.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/PackWriter.java\n@@ -237,6 +237,7 @@ public PackWriter(final Repository repo, final ProgressMonitor imonitor,\n \t\tinitMonitor = imonitor;\n \t\twriteMonitor = wmonitor;\n \t\tthis.deflater = new Deflater(db.getConfig().getCore().getCompression());\n+\t\toutputVersion = repo.getConfig().getCore().getPackIndexVersion();\n \t}\n \n \t/**\n-- \n1.6.2.rc0.204.gf6b427\n"}]}