aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/internal
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2024-11-26 14:37:00 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2024-11-26 14:37:00 +0100
commit683d444ca98fae7c0c6b1cb73f7278dd9114fcab (patch)
treee60d8a1c2d2eb802d71a90b0456e333fdb0cb331 /org.eclipse.jgit/src/org/eclipse/jgit/internal
parent6fa28d7677f8242d73dc32294fa7db6e86c23b25 (diff)
parente3eabe5d5cc9bd4f43f18014cac70e80b55cb45b (diff)
downloadjgit-683d444ca98fae7c0c6b1cb73f7278dd9114fcab.tar.gz
jgit-683d444ca98fae7c0c6b1cb73f7278dd9114fcab.zip
Merge branch 'stable-7.0'
* stable-7.0: PackDirectory: Filter out tmp GC pack files Test advertised capabilities with protocol V0 and allow*Sha1InWant Align request policies with CGit Pack.java: Recover more often in Pack.copyAsIs2() Change-Id: Iddb994a747bc860dd9286e74190ecdd285ce6832
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/internal')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java295
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java8
3 files changed, 162 insertions, 143 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
index be457644d9..3518342f97 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
@@ -416,185 +416,196 @@ public class Pack implements Iterable<PackIndex.MutableEntry> {
final CRC32 crc2 = validate ? new CRC32() : null;
final byte[] buf = out.getCopyBuffer();
+ boolean isHeaderWritten = false;
// Rip apart the header so we can discover the size.
//
- readFully(src.offset, buf, 0, 20, curs);
- int c = buf[0] & 0xff;
- final int typeCode = (c >> 4) & 7;
- long inflatedLength = c & 15;
- int shift = 4;
- int headerCnt = 1;
- while ((c & 0x80) != 0) {
- c = buf[headerCnt++] & 0xff;
- inflatedLength += ((long) (c & 0x7f)) << shift;
- shift += 7;
- }
-
- if (typeCode == Constants.OBJ_OFS_DELTA) {
- do {
+ try {
+ readFully(src.offset, buf, 0, 20, curs);
+
+ int c = buf[0] & 0xff;
+ final int typeCode = (c >> 4) & 7;
+ long inflatedLength = c & 15;
+ int shift = 4;
+ int headerCnt = 1;
+ while ((c & 0x80) != 0) {
c = buf[headerCnt++] & 0xff;
- } while ((c & 128) != 0);
- if (validate) {
- assert(crc1 != null && crc2 != null);
- crc1.update(buf, 0, headerCnt);
- crc2.update(buf, 0, headerCnt);
+ inflatedLength += ((long) (c & 0x7f)) << shift;
+ shift += 7;
}
- } else if (typeCode == Constants.OBJ_REF_DELTA) {
- if (validate) {
+
+ if (typeCode == Constants.OBJ_OFS_DELTA) {
+ do {
+ c = buf[headerCnt++] & 0xff;
+ } while ((c & 128) != 0);
+ if (validate) {
+ assert(crc1 != null && crc2 != null);
+ crc1.update(buf, 0, headerCnt);
+ crc2.update(buf, 0, headerCnt);
+ }
+ } else if (typeCode == Constants.OBJ_REF_DELTA) {
+ if (validate) {
+ assert(crc1 != null && crc2 != null);
+ crc1.update(buf, 0, headerCnt);
+ crc2.update(buf, 0, headerCnt);
+ }
+
+ readFully(src.offset + headerCnt, buf, 0, 20, curs);
+ if (validate) {
+ assert(crc1 != null && crc2 != null);
+ crc1.update(buf, 0, 20);
+ crc2.update(buf, 0, 20);
+ }
+ headerCnt += 20;
+ } else if (validate) {
assert(crc1 != null && crc2 != null);
crc1.update(buf, 0, headerCnt);
crc2.update(buf, 0, headerCnt);
}
- readFully(src.offset + headerCnt, buf, 0, 20, curs);
- if (validate) {
- assert(crc1 != null && crc2 != null);
- crc1.update(buf, 0, 20);
- crc2.update(buf, 0, 20);
- }
- headerCnt += 20;
- } else if (validate) {
- assert(crc1 != null && crc2 != null);
- crc1.update(buf, 0, headerCnt);
- crc2.update(buf, 0, headerCnt);
- }
+ final long dataOffset = src.offset + headerCnt;
+ final long dataLength = src.length;
+ final long expectedCRC;
+ final ByteArrayWindow quickCopy;
- final long dataOffset = src.offset + headerCnt;
- final long dataLength = src.length;
- final long expectedCRC;
- final ByteArrayWindow quickCopy;
-
- // Verify the object isn't corrupt before sending. If it is,
- // we report it missing instead.
- //
- try {
- quickCopy = curs.quickCopy(this, dataOffset, dataLength);
+ // Verify the object isn't corrupt before sending. If it is,
+ // we report it missing instead.
+ //
+ try {
+ quickCopy = curs.quickCopy(this, dataOffset, dataLength);
- if (validate && idx().hasCRC32Support()) {
- assert(crc1 != null);
- // Index has the CRC32 code cached, validate the object.
- //
- expectedCRC = idx().findCRC32(src);
- if (quickCopy != null) {
- quickCopy.crc32(crc1, dataOffset, (int) dataLength);
- } else {
- long pos = dataOffset;
- long cnt = dataLength;
- while (cnt > 0) {
- final int n = (int) Math.min(cnt, buf.length);
- readFully(pos, buf, 0, n, curs);
- crc1.update(buf, 0, n);
- pos += n;
- cnt -= n;
+ if (validate && idx().hasCRC32Support()) {
+ assert(crc1 != null);
+ // Index has the CRC32 code cached, validate the object.
+ //
+ expectedCRC = idx().findCRC32(src);
+ if (quickCopy != null) {
+ quickCopy.crc32(crc1, dataOffset, (int) dataLength);
+ } else {
+ long pos = dataOffset;
+ long cnt = dataLength;
+ while (cnt > 0) {
+ final int n = (int) Math.min(cnt, buf.length);
+ readFully(pos, buf, 0, n, curs);
+ crc1.update(buf, 0, n);
+ pos += n;
+ cnt -= n;
+ }
}
+ if (crc1.getValue() != expectedCRC) {
+ setCorrupt(src.offset);
+ throw new CorruptObjectException(MessageFormat.format(
+ JGitText.get().objectAtHasBadZlibStream,
+ Long.valueOf(src.offset), getPackFile()));
+ }
+ } else if (validate) {
+ // We don't have a CRC32 code in the index, so compute it
+ // now while inflating the raw data to get zlib to tell us
+ // whether or not the data is safe.
+ //
+ Inflater inf = curs.inflater();
+ byte[] tmp = new byte[1024];
+ if (quickCopy != null) {
+ quickCopy.check(inf, tmp, dataOffset, (int) dataLength);
+ } else {
+ assert(crc1 != null);
+ long pos = dataOffset;
+ long cnt = dataLength;
+ while (cnt > 0) {
+ final int n = (int) Math.min(cnt, buf.length);
+ readFully(pos, buf, 0, n, curs);
+ crc1.update(buf, 0, n);
+ inf.setInput(buf, 0, n);
+ while (inf.inflate(tmp, 0, tmp.length) > 0)
+ continue;
+ pos += n;
+ cnt -= n;
+ }
+ }
+ if (!inf.finished() || inf.getBytesRead() != dataLength) {
+ setCorrupt(src.offset);
+ throw new EOFException(MessageFormat.format(
+ JGitText.get().shortCompressedStreamAt,
+ Long.valueOf(src.offset)));
+ }
+ assert(crc1 != null);
+ expectedCRC = crc1.getValue();
+ } else {
+ expectedCRC = -1;
}
- if (crc1.getValue() != expectedCRC) {
- setCorrupt(src.offset);
- throw new CorruptObjectException(MessageFormat.format(
- JGitText.get().objectAtHasBadZlibStream,
- Long.valueOf(src.offset), getPackFile()));
- }
- } else if (validate) {
- // We don't have a CRC32 code in the index, so compute it
- // now while inflating the raw data to get zlib to tell us
- // whether or not the data is safe.
+ } catch (DataFormatException dataFormat) {
+ setCorrupt(src.offset);
+
+ CorruptObjectException corruptObject = new CorruptObjectException(
+ MessageFormat.format(
+ JGitText.get().objectAtHasBadZlibStream,
+ Long.valueOf(src.offset), getPackFile()),
+ dataFormat);
+
+ throw new StoredObjectRepresentationNotAvailableException(
+ corruptObject);
+ }
+
+ if (quickCopy != null) {
+ // The entire object fits into a single byte array window slice,
+ // and we have it pinned. Write this out without copying.
//
- Inflater inf = curs.inflater();
- byte[] tmp = new byte[1024];
- if (quickCopy != null) {
- quickCopy.check(inf, tmp, dataOffset, (int) dataLength);
- } else {
- assert(crc1 != null);
+ out.writeHeader(src, inflatedLength);
+ isHeaderWritten = true;
+ quickCopy.write(out, dataOffset, (int) dataLength);
+
+ } else if (dataLength <= buf.length) {
+ // Tiny optimization: Lots of objects are very small deltas or
+ // deflated commits that are likely to fit in the copy buffer.
+ //
+ if (!validate) {
long pos = dataOffset;
long cnt = dataLength;
while (cnt > 0) {
final int n = (int) Math.min(cnt, buf.length);
readFully(pos, buf, 0, n, curs);
- crc1.update(buf, 0, n);
- inf.setInput(buf, 0, n);
- while (inf.inflate(tmp, 0, tmp.length) > 0)
- continue;
pos += n;
cnt -= n;
}
}
- if (!inf.finished() || inf.getBytesRead() != dataLength) {
- setCorrupt(src.offset);
- throw new EOFException(MessageFormat.format(
- JGitText.get().shortCompressedStreamAt,
- Long.valueOf(src.offset)));
- }
- assert(crc1 != null);
- expectedCRC = crc1.getValue();
+ out.writeHeader(src, inflatedLength);
+ isHeaderWritten = true;
+ out.write(buf, 0, (int) dataLength);
} else {
- expectedCRC = -1;
- }
- } catch (DataFormatException dataFormat) {
- setCorrupt(src.offset);
-
- CorruptObjectException corruptObject = new CorruptObjectException(
- MessageFormat.format(
- JGitText.get().objectAtHasBadZlibStream,
- Long.valueOf(src.offset), getPackFile()),
- dataFormat);
-
- throw new StoredObjectRepresentationNotAvailableException(
- corruptObject);
-
- } catch (IOException ioError) {
- throw new StoredObjectRepresentationNotAvailableException(ioError);
- }
-
- if (quickCopy != null) {
- // The entire object fits into a single byte array window slice,
- // and we have it pinned. Write this out without copying.
- //
- out.writeHeader(src, inflatedLength);
- quickCopy.write(out, dataOffset, (int) dataLength);
-
- } else if (dataLength <= buf.length) {
- // Tiny optimization: Lots of objects are very small deltas or
- // deflated commits that are likely to fit in the copy buffer.
- //
- if (!validate) {
+ // Now we are committed to sending the object. As we spool it out,
+ // check its CRC32 code to make sure there wasn't corruption between
+ // the verification we did above, and us actually outputting it.
+ //
long pos = dataOffset;
long cnt = dataLength;
while (cnt > 0) {
final int n = (int) Math.min(cnt, buf.length);
readFully(pos, buf, 0, n, curs);
+ if (validate) {
+ assert(crc2 != null);
+ crc2.update(buf, 0, n);
+ }
+ if (!isHeaderWritten) {
+ out.writeHeader(src, inflatedLength);
+ isHeaderWritten = true;
+ }
+ out.write(buf, 0, n);
pos += n;
cnt -= n;
}
- }
- out.writeHeader(src, inflatedLength);
- out.write(buf, 0, (int) dataLength);
- } else {
- // Now we are committed to sending the object. As we spool it out,
- // check its CRC32 code to make sure there wasn't corruption between
- // the verification we did above, and us actually outputting it.
- //
- out.writeHeader(src, inflatedLength);
- long pos = dataOffset;
- long cnt = dataLength;
- while (cnt > 0) {
- final int n = (int) Math.min(cnt, buf.length);
- readFully(pos, buf, 0, n, curs);
if (validate) {
assert(crc2 != null);
- crc2.update(buf, 0, n);
+ if (crc2.getValue() != expectedCRC) {
+ throw new CorruptObjectException(MessageFormat.format(
+ JGitText.get().objectAtHasBadZlibStream,
+ Long.valueOf(src.offset), getPackFile()));
+ }
}
- out.write(buf, 0, n);
- pos += n;
- cnt -= n;
}
- if (validate) {
- assert(crc2 != null);
- if (crc2.getValue() != expectedCRC) {
- throw new CorruptObjectException(MessageFormat.format(
- JGitText.get().objectAtHasBadZlibStream,
- Long.valueOf(src.offset), getPackFile()));
- }
+ } catch (IOException ioError) {
+ if (!isHeaderWritten) {
+ throw new StoredObjectRepresentationNotAvailableException(ioError);
}
+ throw ioError;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
index 8221cff442..51a8148838 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
@@ -545,7 +545,7 @@ class PackDirectory {
for (String name : nameList) {
try {
PackFile pack = new PackFile(directory, name);
- if (pack.getPackExt() != null) {
+ if (pack.getPackExt() != null && !pack.isTmpGCFile()) {
Map<PackExt, PackFile> packByExt = packFilesByExtById
.get(pack.getId());
if (packByExt == null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
index 19979d0ed5..c9b05ad025 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
@@ -27,6 +27,7 @@ public class PackFile extends File {
private static final long serialVersionUID = 1L;
private static final String PREFIX = "pack-"; //$NON-NLS-1$
+ private static final String TMP_GC_PREFIX = ".tmp-"; //$NON-NLS-1$
private final String base; // PREFIX + id i.e.
// pack-0123456789012345678901234567890123456789
@@ -126,6 +127,13 @@ public class PackFile extends File {
}
/**
+ * @return whether the file is a temporary GC file
+ */
+ public boolean isTmpGCFile() {
+ return id.startsWith(TMP_GC_PREFIX);
+ }
+
+ /**
* Create a new similar PackFile with the given extension instead.
*
* @param ext