diff --git a/org.eclipse.jgit.benchmarks/BUILD b/org.eclipse.jgit.benchmarks/BUILD
index 7e331b101..ecd268c4b 100644
--- a/org.eclipse.jgit.benchmarks/BUILD
+++ b/org.eclipse.jgit.benchmarks/BUILD
@@ -8,6 +8,8 @@ jmh_java_benchmarks(
name = "benchmarks",
srcs = SRCS,
deps = [
+ "//lib:javaewah",
+ "//lib:slf4j-api",
"//org.eclipse.jgit:jgit",
],
)
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 7ff001e1e..38be93bd4 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -294,7 +294,7 @@
org.eclipse.cbi.maven.plugins
eclipse-jarsigner-plugin
- 1.3.1
+ 1.3.2
org.codehaus.mojo
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java
index 15c9109ca..32342e356 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java
@@ -25,7 +25,9 @@
import static org.junit.Assert.fail;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collection;
@@ -133,20 +135,21 @@ public void testConvert() throws Exception {
assertTrue(db.getRefDatabase().hasFastTipsWithSha1());
}
+
@Test
- public void testConvertToRefdir() throws Exception {
+ public void testConvertBrokenObjectId() throws Exception {
db.convertToPackedRefs(false, false);
- assertTrue(db.getRefDatabase() instanceof RefDirectory);
- Ref h = db.exactRef("HEAD");
- assertTrue(h.isSymbolic());
- assertEquals("refs/heads/master", h.getTarget().getName());
+ new File(db.getDirectory(), "refs/heads").mkdirs();
- Ref b = db.exactRef("refs/heads/b");
- assertFalse(b.isSymbolic());
- assertTrue(b.isPeeled());
- assertEquals(bCommit, b.getObjectId().name());
+ String invalidId = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
+ File headFile = new File(db.getDirectory(), "refs/heads/broken");
+ try (OutputStream os = new FileOutputStream(headFile)) {
+ os.write(Constants.encodeASCII(invalidId + "\n"));
+ }
- assertFalse(db.getRefDatabase().hasFastTipsWithSha1());
+ Ref r = db.exactRef("refs/heads/broken");
+ assertNotNull(r);
+ db.convertToReftable(true, false);
}
@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
index 0d739b927..ea0d92acf 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
@@ -941,6 +941,12 @@ public void logScan() throws IOException {
}
assertFalse(lc.next());
}
+
+ for (Ref exp : refs) {
+ try (LogCursor lc = t.seekLog(exp.getName())) {
+ assertTrue("has " + exp.getName(), lc.next());
+ }
+ }
}
@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackLsRefsFileRepositoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackLsRefsFileRepositoryTest.java
new file mode 100644
index 000000000..7d5fc6101
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackLsRefsFileRepositoryTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2021, Saša Živkov and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.transport;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Sets;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTag;
+import org.junit.Before;
+import org.junit.Test;
+
+// TODO: refactor UploadPackTest to run against both DfsRepository and FileRepository
+public class UploadPackLsRefsFileRepositoryTest
+ extends LocalDiskRepositoryTestCase {
+
+ private FileRepository server;
+
+ private TestRepository remote;
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ server = createWorkRepository();
+ remote = new TestRepository<>(server);
+ }
+
+ @Test
+ public void testV2LsRefsPeel() throws Exception {
+ RevCommit tip = remote.commit().message("message").create();
+ remote.update("master", tip);
+ server.updateRef("HEAD").link("refs/heads/master");
+ RevTag tag = remote.tag("tag", tip);
+ remote.update("refs/tags/tag", tag);
+
+ ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n",
+ PacketLineIn.delimiter(), "peel", PacketLineIn.end());
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+ assertThat(pckIn.readString(),
+ is(tip.toObjectId().getName() + " HEAD"));
+ assertThat(pckIn.readString(),
+ is(tip.toObjectId().getName() + " refs/heads/master"));
+ assertThat(pckIn.readString(), is(tag.toObjectId().getName()
+ + " refs/tags/tag peeled:" + tip.toObjectId().getName()));
+ assertTrue(PacketLineIn.isEnd(pckIn.readString()));
+ }
+
+ private ByteArrayInputStream uploadPackV2(String... inputLines)
+ throws Exception {
+ return uploadPackV2(null, inputLines);
+ }
+
+ private ByteArrayInputStream uploadPackV2(
+ Consumer postConstructionSetup, String... inputLines)
+ throws Exception {
+ ByteArrayInputStream recvStream = uploadPackV2Setup(
+ postConstructionSetup, inputLines);
+ PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+ // drain capabilities
+ while (!PacketLineIn.isEnd(pckIn.readString())) {
+ // do nothing
+ }
+ return recvStream;
+ }
+
+ private ByteArrayInputStream uploadPackV2Setup(
+ Consumer postConstructionSetup, String... inputLines)
+ throws Exception {
+
+ ByteArrayInputStream send = linesAsInputStream(inputLines);
+
+ server.getConfig().setString("protocol", null, "version", "2");
+ UploadPack up = new UploadPack(server);
+ if (postConstructionSetup != null) {
+ postConstructionSetup.accept(up);
+ }
+ up.setExtraParameters(Sets.of("version=2"));
+
+ ByteArrayOutputStream recv = new ByteArrayOutputStream();
+ up.upload(send, recv, null);
+
+ return new ByteArrayInputStream(recv.toByteArray());
+ }
+
+ private static ByteArrayInputStream linesAsInputStream(String... inputLines)
+ throws IOException {
+ try (ByteArrayOutputStream send = new ByteArrayOutputStream()) {
+ PacketLineOut pckOut = new PacketLineOut(send);
+ for (String line : inputLines) {
+ Objects.requireNonNull(line);
+ if (PacketLineIn.isEnd(line)) {
+ pckOut.end();
+ } else if (PacketLineIn.isDelimiter(line)) {
+ pckOut.writeDelim();
+ } else {
+ pckOut.writeString(line);
+ }
+ }
+ return new ByteArrayInputStream(send.toByteArray());
+ }
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
index a80fa837b..e9e17c0ec 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
@@ -28,6 +28,7 @@
import java.util.stream.Collectors;
import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.events.RefsChangedEvent;
import org.eclipse.jgit.internal.storage.reftable.MergedReftable;
import org.eclipse.jgit.internal.storage.reftable.ReftableBatchRefUpdate;
@@ -592,15 +593,20 @@ private static Ref refForWrite(RevWalk rw, Ref r) throws IOException {
r.getTarget().getName(), null));
}
ObjectId newId = r.getObjectId();
- RevObject obj = rw.parseAny(newId);
RevObject peel = null;
- if (obj instanceof RevTag) {
- peel = rw.peel(obj);
+ try {
+ RevObject obj = rw.parseAny(newId);
+ if (obj instanceof RevTag) {
+ peel = rw.peel(obj);
+ }
+ } catch (MissingObjectException e) {
+ /* ignore this error and copy the dangling object ID into reftable too. */
}
if (peel != null) {
- return new ObjectIdRef.PeeledTag(PACKED, r.getName(), newId,
- peel.copy());
- }
+ return new ObjectIdRef.PeeledTag(PACKED, r.getName(), newId,
+ peel.copy());
+ }
+
return new ObjectIdRef.PeeledNonTag(PACKED, r.getName(), newId);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
index 009631289..d07713db8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
@@ -59,7 +59,6 @@
class BlockReader {
private byte blockType;
private long endPosition;
- private boolean truncated;
private byte[] buf;
private int bufLen;
@@ -79,10 +78,6 @@ byte type() {
return blockType;
}
- boolean truncated() {
- return truncated;
- }
-
long endPosition() {
return endPosition;
}
@@ -298,16 +293,8 @@ private void parseBlockStart(BlockSource src, long pos, int fileBlockSize)
// Log blocks must be inflated after the header.
long deflatedSize = inflateBuf(src, pos, blockLen, fileBlockSize);
endPosition = pos + 4 + deflatedSize;
- }
- if (bufLen < blockLen) {
- if (blockType != INDEX_BLOCK_TYPE) {
- throw invalidBlock();
- }
- // Its OK during sequential scan for an index block to have been
- // partially read and be truncated in-memory. This happens when
- // the index block is larger than the file's blockSize. Caller
- // will break out of its scan loop once it sees the blockType.
- truncated = true;
+ } else if (bufLen < blockLen) {
+ readBlockIntoBuf(src, pos, blockLen);
} else if (bufLen > blockLen) {
bufLen = blockLen;
}
@@ -372,7 +359,7 @@ private void setupEmptyFileBlock() {
}
void verifyIndex() throws IOException {
- if (blockType != INDEX_BLOCK_TYPE || truncated) {
+ if (blockType != INDEX_BLOCK_TYPE) {
throw invalidBlock();
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
index 9e2ae9160..cabb2e184 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
@@ -435,7 +435,7 @@ private BlockReader readBlock(long pos, long end) throws IOException {
BlockReader b = new BlockReader();
b.readBlock(src, pos, sz);
- if (b.type() == INDEX_BLOCK_TYPE && !b.truncated()) {
+ if (b.type() == INDEX_BLOCK_TYPE) {
if (indexCache == null) {
indexCache = new LongMap<>();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index 7f1ddaab2..9fda63928 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -1090,6 +1090,7 @@ private void lsRefsV2(PacketLineOut pckOut) throws IOException {
rawOut.stopBuffering();
PacketLineOutRefAdvertiser adv = new PacketLineOutRefAdvertiser(pckOut);
+ adv.init(db);
adv.setUseProtocolV2(true);
if (req.getPeel()) {
adv.setDerefTags(true);
diff --git a/pom.xml b/pom.xml
index 5c5a4c7b9..464bee9a4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -330,7 +330,7 @@
org.eclipse.cbi.maven.plugins
eclipse-jarsigner-plugin
- 1.3.1
+ 1.3.2
org.eclipse.tycho.extras