diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java index edced2fbb..3483b9d16 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java @@ -66,6 +66,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.storage.file.ObjectDirectory; +import org.eclipse.jgit.storage.pack.BinaryDelta; import org.eclipse.jgit.util.NB; import org.eclipse.jgit.util.TemporaryBuffer; @@ -271,16 +272,24 @@ private void receive(final ReceivePack rp, } public void testUsingHiddenDeltaBaseFails() throws Exception { + byte[] delta = { 0x1, 0x1, 0x1, 'c' }; + TestRepository s = new TestRepository(src); + RevCommit N = s.commit().parent(B).add("q", + s.blob(BinaryDelta.apply(dst.open(b).getCachedBytes(), delta))) + .create(); + final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); - packHeader(pack, 1); + packHeader(pack, 3); + copy(pack, src.open(N)); + copy(pack, src.open(s.parseBody(N).getTree())); pack.write((Constants.OBJ_REF_DELTA) << 4 | 4); b.copyRawTo(pack); - deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' }); + deflate(pack, delta); digest(pack); - final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(256); + final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); final PacketLineOut inPckLine = new PacketLineOut(inBuf); - inPckLine.writeString(ObjectId.zeroId().name() + ' ' + P.name() + ' ' + inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' ' + "refs/heads/s" + '\0' + BasePackPushConnection.CAPABILITY_REPORT_STATUS); inPckLine.end(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java index 2fb342dad..20c4bb0f9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java @@ -994,7 +994,7 @@ private ObjectWalk setUpWalker( final ObjectWalk walker = new ObjectWalk(reader); walker.setRetainBody(false); - walker.sort(RevSort.COMMIT_TIME_DESC); + walker.sort(RevSort.TOPO); if (thin && !not.isEmpty()) walker.sort(RevSort.BOUNDARY, true); 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 36ee2fedf..4cc9ea58b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -84,6 +84,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevFlag; import org.eclipse.jgit.revwalk.RevObject; +import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.file.PackLock; @@ -811,6 +812,11 @@ private void checkConnectivity() throws IOException { final ObjectWalk ow = new ObjectWalk(db); ow.setRetainBody(false); + if (checkReferencedIsReachable) { + ow.sort(RevSort.TOPO); + if (!baseObjects.isEmpty()) + ow.sort(RevSort.BOUNDARY, true); + } for (final ReceiveCommand cmd : commands) { if (cmd.getResult() != Result.NOT_ATTEMPTED) @@ -832,22 +838,19 @@ private void checkConnectivity() throws IOException { } } - if (checkReferencedIsReachable) { - for (ObjectId id : baseObjects) { - RevObject b = ow.lookupAny(id, Constants.OBJ_BLOB); - if (!b.has(RevFlag.UNINTERESTING)) - throw new MissingObjectException(b, b.getType()); - } - } - RevCommit c; while ((c = ow.next()) != null) { - if (checkReferencedIsReachable && !providedObjects.contains(c)) + if (checkReferencedIsReachable // + && !c.has(RevFlag.UNINTERESTING) // + && !providedObjects.contains(c)) throw new MissingObjectException(c, Constants.TYPE_COMMIT); } RevObject o; while ((o = ow.nextObject()) != null) { + if (o.has(RevFlag.UNINTERESTING)) + continue; + if (checkReferencedIsReachable) { if (providedObjects.contains(o)) continue; @@ -858,6 +861,14 @@ private void checkConnectivity() throws IOException { if (o instanceof RevBlob && !db.hasObject(o)) throw new MissingObjectException(o, Constants.TYPE_BLOB); } + + if (checkReferencedIsReachable) { + for (ObjectId id : baseObjects) { + o = ow.parseAny(id); + if (!o.has(RevFlag.UNINTERESTING)) + throw new MissingObjectException(o, o.getType()); + } + } } private void validateCommands() {