From b4b8f05eea80d4bf6e17db12e721c24ff3e32c9a Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Fri, 28 Jul 2023 11:41:26 +0200 Subject: [PATCH 01/17] DfsReader: Expose when indices are loaded We want to measure the data used to serve a request. As a first step, we want to know how many indices are accessed during the request and their sizes. Expose an interface in DfsReader to announce when an index is loaded into the reader, i.e. when its reference is set. The interface is more flexible to implementors (what/how to collect) than the existing DfsReaderIOStats object. Change-Id: I56f7658fde1758efaf869fa779d11b533a81a0a7 --- .../internal/storage/dfs/DfsPackFileTest.java | 91 +++++++++++ .../internal/storage/dfs/DfsReaderTest.java | 142 +++++++++++++++--- .../internal/storage/dfs/BlockBasedFile.java | 4 +- .../internal/storage/dfs/DfsPackFile.java | 11 +- .../jgit/internal/storage/dfs/DfsReader.java | 98 ++++++++++++ 5 files changed, 321 insertions(+), 25 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java index 298812d6e..82fc56347 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java @@ -18,8 +18,12 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.zip.Deflater; +import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; +import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.pack.PackOutputStream; import org.eclipse.jgit.internal.storage.pack.PackWriter; @@ -130,6 +134,93 @@ public void testLoadObjectSizeIndex_noIndex() throws IOException { assertFalse(pack.hasObjectSizeIndex(reader)); } + private static class TestPackLoadListener implements PackLoadListener { + final Map indexLoadCount = new HashMap<>(); + + int blockLoadCount; + + @Override + public void onIndexLoad(String packName, PackSource src, PackExt ext, + long size, Object loadedIdx) { + indexLoadCount.merge(ext, 1, Integer::sum); + } + + @Override + public void onBlockLoad(String packName, PackSource src, PackExt ext, long position, + DfsBlockData dfsBlockData) { + blockLoadCount += 1; + } + } + + @Test + public void testIndexLoadCallback_indexNotInCache() throws IOException { + bypassCache = false; + clearCache = true; + setObjectSizeIndexMinBytes(-1); + setupPack(512, 800); + + TestPackLoadListener tal = new TestPackLoadListener(); + DfsReader reader = db.getObjectDatabase().newReader(); + reader.addPackLoadListener(tal); + DfsPackFile pack = db.getObjectDatabase().getPacks()[0]; + pack.getPackIndex(reader); + + assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue()); + } + + @Test + public void testIndexLoadCallback_indexInCache() throws IOException { + bypassCache = false; + clearCache = false; + setObjectSizeIndexMinBytes(-1); + setupPack(512, 800); + + TestPackLoadListener tal = new TestPackLoadListener(); + DfsReader reader = db.getObjectDatabase().newReader(); + reader.addPackLoadListener(tal); + DfsPackFile pack = db.getObjectDatabase().getPacks()[0]; + pack.getPackIndex(reader); + pack.getPackIndex(reader); + pack.getPackIndex(reader); + + assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue()); + } + + @Test + public void testIndexLoadCallback_multipleReads() throws IOException { + bypassCache = false; + clearCache = true; + setObjectSizeIndexMinBytes(-1); + setupPack(512, 800); + + TestPackLoadListener tal = new TestPackLoadListener(); + DfsReader reader = db.getObjectDatabase().newReader(); + reader.addPackLoadListener(tal); + DfsPackFile pack = db.getObjectDatabase().getPacks()[0]; + pack.getPackIndex(reader); + pack.getPackIndex(reader); + pack.getPackIndex(reader); + + assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue()); + } + + + @Test + public void testBlockLoadCallback_loadInCache() throws IOException { + bypassCache = false; + clearCache = true; + setObjectSizeIndexMinBytes(-1); + setupPack(512, 800); + + TestPackLoadListener tal = new TestPackLoadListener(); + DfsReader reader = db.getObjectDatabase().newReader(); + reader.addPackLoadListener(tal); + DfsPackFile pack = db.getObjectDatabase().getPacks()[0]; + ObjectId anObject = pack.getPackIndex(reader).getObjectId(0); + pack.get(reader, anObject).getBytes(); + assertEquals(2, tal.blockLoadCount); + } + private ObjectId setupPack(int bs, int ps) throws IOException { DfsBlockCacheConfig cfg = new DfsBlockCacheConfig().setBlockSize(bs) .setBlockLimit(bs * 100).setStreamRatio(bypassCache ? 0F : 1F); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java index 4dd7ba494..8fc9a0adf 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java @@ -11,15 +11,20 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION; +import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; +import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener; +import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.TestRng; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.junit.Before; @@ -40,31 +45,31 @@ public void isNotLargerThan_objAboveThreshold() ObjectId obj = insertBlobWithSize(200); try (DfsReader ctx = db.getObjectDatabase().newReader()) { assertFalse("limit < threshold < obj", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 50)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 50)); assertEquals(1, ctx.stats.isNotLargerThanCallCount); assertEquals(1, ctx.stats.objectSizeIndexHit); assertEquals(0, ctx.stats.objectSizeIndexMiss); assertFalse("limit = threshold < obj", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 100)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 100)); assertEquals(2, ctx.stats.isNotLargerThanCallCount); assertEquals(2, ctx.stats.objectSizeIndexHit); assertEquals(0, ctx.stats.objectSizeIndexMiss); assertFalse("threshold < limit < obj", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 150)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 150)); assertEquals(3, ctx.stats.isNotLargerThanCallCount); assertEquals(3, ctx.stats.objectSizeIndexHit); assertEquals(0, ctx.stats.objectSizeIndexMiss); assertTrue("threshold < limit = obj", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 200)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 200)); assertEquals(4, ctx.stats.isNotLargerThanCallCount); assertEquals(4, ctx.stats.objectSizeIndexHit); assertEquals(0, ctx.stats.objectSizeIndexMiss); assertTrue("threshold < obj < limit", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 250)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 250)); assertEquals(5, ctx.stats.isNotLargerThanCallCount); assertEquals(5, ctx.stats.objectSizeIndexHit); assertEquals(0, ctx.stats.objectSizeIndexMiss); @@ -80,31 +85,31 @@ public void isNotLargerThan_objBelowThreshold() ObjectId obj = insertBlobWithSize(50); try (DfsReader ctx = db.getObjectDatabase().newReader()) { assertFalse("limit < obj < threshold", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 10)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 10)); assertEquals(1, ctx.stats.isNotLargerThanCallCount); assertEquals(0, ctx.stats.objectSizeIndexHit); assertEquals(1, ctx.stats.objectSizeIndexMiss); assertTrue("limit = obj < threshold", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 50)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 50)); assertEquals(2, ctx.stats.isNotLargerThanCallCount); assertEquals(0, ctx.stats.objectSizeIndexHit); assertEquals(2, ctx.stats.objectSizeIndexMiss); assertTrue("obj < limit < threshold", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 80)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 80)); assertEquals(3, ctx.stats.isNotLargerThanCallCount); assertEquals(0, ctx.stats.objectSizeIndexHit); assertEquals(3, ctx.stats.objectSizeIndexMiss); assertTrue("obj < limit = threshold", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 100)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 100)); assertEquals(4, ctx.stats.isNotLargerThanCallCount); assertEquals(0, ctx.stats.objectSizeIndexHit); assertEquals(4, ctx.stats.objectSizeIndexMiss); assertTrue("obj < threshold < limit", - ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 120)); + ctx.isNotLargerThan(obj, OBJ_BLOB, 120)); assertEquals(5, ctx.stats.isNotLargerThanCallCount); assertEquals(0, ctx.stats.objectSizeIndexHit); assertEquals(5, ctx.stats.objectSizeIndexMiss); @@ -116,11 +121,11 @@ public void isNotLargerThan_emptyIdx() throws IOException { setObjectSizeIndexMinBytes(100); ObjectId obj = insertBlobWithSize(10); try (DfsReader ctx = db.getObjectDatabase().newReader()) { - assertFalse(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 0)); - assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 10)); - assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 40)); - assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 50)); - assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 100)); + assertFalse(ctx.isNotLargerThan(obj, OBJ_BLOB, 0)); + assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 10)); + assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 40)); + assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 50)); + assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 100)); assertEquals(5, ctx.stats.isNotLargerThanCallCount); assertEquals(5, ctx.stats.objectSizeIndexMiss); @@ -133,11 +138,11 @@ public void isNotLargerThan_noObjectSizeIndex() throws IOException { setObjectSizeIndexMinBytes(-1); ObjectId obj = insertBlobWithSize(10); try (DfsReader ctx = db.getObjectDatabase().newReader()) { - assertFalse(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 0)); - assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 10)); - assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 40)); - assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 50)); - assertTrue(ctx.isNotLargerThan(obj, Constants.OBJ_BLOB, 100)); + assertFalse(ctx.isNotLargerThan(obj, OBJ_BLOB, 0)); + assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 10)); + assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 40)); + assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 50)); + assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 100)); assertEquals(5, ctx.stats.isNotLargerThanCallCount); assertEquals(0, ctx.stats.objectSizeIndexMiss); @@ -145,12 +150,103 @@ public void isNotLargerThan_noObjectSizeIndex() throws IOException { } } + @Test + public void packLoadListener_noInvocations() throws IOException { + insertBlobWithSize(100); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + CounterPackLoadListener listener = new CounterPackLoadListener(); + ctx.addPackLoadListener(listener); + assertEquals(null, listener.callsPerExt.get(PackExt.INDEX)); + } + } + + @Test + public void packLoadListener_has_openIdx() throws IOException { + ObjectId obj = insertBlobWithSize(100); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + CounterPackLoadListener listener = new CounterPackLoadListener(); + ctx.addPackLoadListener(listener); + boolean has = ctx.has(obj); + assertTrue(has); + assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.INDEX)); + } + } + + @Test + public void packLoadListener_notLargerThan_openMultipleIndices() throws IOException { + setObjectSizeIndexMinBytes(100); + ObjectId obj = insertBlobWithSize(200); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + CounterPackLoadListener listener = new CounterPackLoadListener(); + ctx.addPackLoadListener(listener); + boolean notLargerThan = ctx.isNotLargerThan(obj, OBJ_BLOB, 1000); + assertTrue(notLargerThan); + assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.INDEX)); + assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.OBJECT_SIZE_INDEX)); + } + } + + @Test + public void packLoadListener_has_openMultipleIndices() throws IOException { + setObjectSizeIndexMinBytes(100); + insertBlobWithSize(200); + insertBlobWithSize(230); + insertBlobWithSize(100); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + CounterPackLoadListener listener = new CounterPackLoadListener(); + ctx.addPackLoadListener(listener); + ObjectId oid = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f129"); + boolean has = ctx.has(oid); + assertFalse(has); + // Open 3 indices trying to find the pack + assertEquals(Integer.valueOf(3), listener.callsPerExt.get(PackExt.INDEX)); + } + } + + + @Test + public void packLoadListener_has_repeatedCalls_openMultipleIndices() throws IOException { + // Two objects NOT in the repo + ObjectId oid = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f129"); + ObjectId oid2 = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f130"); + + setObjectSizeIndexMinBytes(100); + insertBlobWithSize(200); + insertBlobWithSize(230); + insertBlobWithSize(100); + CounterPackLoadListener listener = new CounterPackLoadListener(); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + ctx.addPackLoadListener(listener); + boolean has = ctx.has(oid); + ctx.has(oid); + ctx.has(oid2); + assertFalse(has); + // The 3 indices were loaded only once each + assertEquals(Integer.valueOf(3), listener.callsPerExt.get(PackExt.INDEX)); + } + } + + private static class CounterPackLoadListener implements PackLoadListener { + final Map callsPerExt = new HashMap<>(); + + @Override + public void onIndexLoad(String packName, PackSource src, PackExt ext, long size, + Object loadedIdx) { + callsPerExt.merge(ext, 1, Integer::sum); + } + + @Override + public void onBlockLoad(String packName, PackSource src, PackExt ext, + long size, DfsBlockData dfsBlockData) { + } + } + private ObjectId insertBlobWithSize(int size) throws IOException { TestRng testRng = new TestRng(JGitTestUtil.getName()); ObjectId oid; try (ObjectInserter ins = db.newObjectInserter()) { - oid = ins.insert(Constants.OBJ_BLOB, + oid = ins.insert(OBJ_BLOB, testRng.nextBytes(size)); ins.flush(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java index b1b09baf2..ab0747566 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java @@ -100,7 +100,9 @@ else if (size < cache.getBlockSize()) DfsBlock getOrLoadBlock(long pos, DfsReader ctx) throws IOException { try (LazyChannel c = new LazyChannel(ctx, desc, ext)) { - return cache.getOrLoad(this, pos, ctx, c); + DfsBlock block = cache.getOrLoad(this, pos, ctx, c); + ctx.emitBlockLoad(this, pos, block); + return block; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java index 1f54795de..715c0c76b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java @@ -181,6 +181,7 @@ private PackIndex idx(DfsReader ctx) throws IOException { PackIndex idx = idxref.get(); if (index == null && idx != null) { index = idx; + ctx.emitIndexLoad(desc, INDEX, System.identityHashCode(idx)); } return index; } catch (IOException e) { @@ -226,6 +227,7 @@ public PackBitmapIndex getBitmapIndex(DfsReader ctx) throws IOException { PackBitmapIndex bmidx = idxref.get(); if (bitmapIndex == null && bmidx != null) { bitmapIndex = bmidx; + ctx.emitIndexLoad(desc, BITMAP_INDEX, System.identityHashCode(bmidx)); } return bitmapIndex; } @@ -263,6 +265,7 @@ public CommitGraph getCommitGraph(DfsReader ctx) throws IOException { CommitGraph cg = cgref.get(); if (commitGraph == null && cg != null) { commitGraph = cg; + ctx.emitIndexLoad(desc, COMMIT_GRAPH, System.identityHashCode(cg)); } return commitGraph; } @@ -296,6 +299,7 @@ public PackReverseIndex getReverseIdx(DfsReader ctx) throws IOException { PackReverseIndex revidx = revref.get(); if (reverseIndex == null && revidx != null) { reverseIndex = revidx; + ctx.emitIndexLoad(desc, REVERSE_INDEX, System.identityHashCode(revidx)); } return reverseIndex; } @@ -323,8 +327,9 @@ private PackObjectSizeIndex getObjectSizeIndex(DfsReader ctx) ctx.stats.objectSizeIndexCacheHit++; } PackObjectSizeIndex sizeIdx = sizeIdxRef.get(); - if (sizeIdx != null) { + if (objectSizeIndex == null && sizeIdx != null) { objectSizeIndex = sizeIdx; + ctx.emitIndexLoad(desc, OBJECT_SIZE_INDEX, System.identityHashCode(sizeIdx)); } } finally { objectSizeIndexLoadAttempted = true; @@ -426,6 +431,7 @@ void copyPackAsIs(PackOutputStream out, DfsReader ctx) throws IOException { if (sz > 0) { rc.setReadAheadBytes(sz); } + //TODO(ifrade): report ctx.emitBlockLoaded for this copy if (cache.shouldCopyThroughCache(length)) { copyPackThroughCache(out, ctx, rc); } else { @@ -1171,6 +1177,7 @@ private DfsBlockCache.Ref loadPackIndex( try (ReadableChannel rc = ctx.db.openFile(desc, INDEX)) { PackIndex idx = PackIndex.read(alignTo8kBlocks(rc)); ctx.stats.readIdxBytes += rc.position(); + ctx.emitIndexLoad(desc, INDEX, System.identityHashCode(idx)); index = idx; return new DfsBlockCache.Ref<>( idxKey, @@ -1197,6 +1204,7 @@ private DfsBlockCache.Ref loadReverseIdx( long start = System.nanoTime(); PackReverseIndex revidx = PackReverseIndexFactory.computeFromIndex(idx); reverseIndex = revidx; + ctx.emitIndexLoad(desc, REVERSE_INDEX, System.identityHashCode(revidx)); ctx.stats.readReverseIdxMicros += elapsedMicros(start); return new DfsBlockCache.Ref<>( revKey, @@ -1216,6 +1224,7 @@ private DfsBlockCache.Ref loadObjectSizeIndex( objectSizeIndex = PackObjectSizeIndexLoader .load(Channels.newInputStream(rc)); size = rc.position(); + ctx.emitIndexLoad(desc, OBJECT_SIZE_INDEX, System.identityHashCode(objectSizeIndex)); } catch (IOException e) { parsingError = e; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java index d98ec5856..16344068e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java @@ -34,6 +34,8 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackList; +import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; +import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener.DfsBlockData; import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl; import org.eclipse.jgit.internal.storage.file.PackBitmapIndex; import org.eclipse.jgit.internal.storage.file.PackIndex; @@ -41,6 +43,7 @@ import org.eclipse.jgit.internal.storage.pack.CachedPack; import org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs; import org.eclipse.jgit.internal.storage.pack.ObjectToPack; +import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.pack.PackOutputStream; import org.eclipse.jgit.internal.storage.pack.PackWriter; import org.eclipse.jgit.lib.AbbreviatedObjectId; @@ -79,6 +82,7 @@ public class DfsReader extends ObjectReader implements ObjectReuseAsIs { private DeltaBaseCache baseCache; private DfsPackFile last; private boolean avoidUnreachable; + private List packLoadListeners = new ArrayList<>(); /** * Initialize a new DfsReader @@ -834,6 +838,100 @@ public DfsReaderIoStats getIoStats() { return new DfsReaderIoStats(stats); } + /** Announces when data is loaded by reader */ + interface PackLoadListener { + /** + * Immutable copy of a DFS block metadata + */ + class DfsBlockData { + private final int identityHash; + private final int size; + + static DfsBlockData of(DfsBlock src) { + return new DfsBlockData(src); + } + + private DfsBlockData(DfsBlock src) { + this.identityHash = System.identityHashCode(src); + this.size = src.size(); + } + + int getIdentityHash() { + return identityHash; + } + + int getSize() { + return size; + } + } + + /** + * This is called when an index reference (e.g. primary index, reverse + * index, ...) is set in the reader, regarless if loaded from scratch or + * copied from cache. + * + * During the lifetime of the reader, the reference for an index should + * be set only once. + * + * @param packName + * Name of the pack + * @param src + * Source of the pack (e.g. GC, COMPACT, ...) + * @param ext + * Extension in the pack (e.g. IDX, RIDX, ...) + * @param size + * Size of the data loaded (usually as bytes in disk) + * @param loadedIdx + * reference to the loaded index + */ + void onIndexLoad(String packName, PackSource src, PackExt ext, long size, + Object loadedIdx); + + /** + * This is called when a dfs block is loaded into the reader. + * + * The reader keeps only one block at a time in memory, so during a + * request the same block could be loaded multiple times. + * + * @param packName + * Name of the pack this block belongs to + * @param src + * Source of the pack (e.g. GC, COMPACT, ...) + * @param ext + * Extension in the pack (e.g. PACK or REFTABLE) + * @param position + * Block offset being loaded + * @param dfsBlockData + * Metadata of the block + */ + void onBlockLoad(String packName, PackSource src, PackExt ext, + long position, DfsBlockData dfsBlockData); + } + + void emitIndexLoad(DfsPackDescription packDescription, PackExt ext, + Object loadedIdx) { + packLoadListeners.forEach( + listener -> listener.onIndexLoad(packDescription.getFileName(ext), + packDescription.getPackSource(), ext, + packDescription.getFileSize(ext), loadedIdx)); + } + + void emitBlockLoad(BlockBasedFile file, long position, DfsBlock dfsBlock) { + packLoadListeners + .forEach(listener -> listener.onBlockLoad(file.getFileName(), + file.desc.getPackSource(), file.ext, position, + DfsBlockData.of(dfsBlock))); + } + + /** + * Add listener to record loads by this reader + * + * @param listener a listener + */ + protected void addPackLoadListener(PackLoadListener listener) { + packLoadListeners.add(listener); + } + /** * {@inheritDoc} *

From 6f733369391ab45987f87102e626c851454ed141 Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Wed, 16 Aug 2023 13:26:39 -0700 Subject: [PATCH 02/17] DfsGarbageCollector: put only GC commits into the commit graph GC puts all commits reachable from heads and tags into the GC pack, and commits reachable only from other refs (e.g. refs/changes) into GC_REST. The commit-graph contains all commits in GC and GC_REST. This produces too big commit graphs in some repos, beating the purpose of loading the index. Limit the commit graph to commits reachable from heads and tags (i.e. commits in the GC pack). Change-Id: I4962faea5a726d2ea3e548af0aeae370a6cc8588 --- .../storage/dfs/DfsGarbageCollectorTest.java | 22 ++++++++++--------- .../storage/dfs/DfsGarbageCollector.java | 5 +---- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java index 405e12677..16c34500a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java @@ -979,7 +979,7 @@ public void reftableWithTombstoneNotResurrected() throws Exception { } @Test - public void produceCommitGraphAllRefsIncludedFromDisk() throws Exception { + public void produceCommitGraphOnlyHeadsAndTags() throws Exception { String tag = "refs/tags/tag1"; String head = "refs/heads/head1"; String nonHead = "refs/something/nonHead"; @@ -1001,19 +1001,20 @@ public void produceCommitGraphAllRefsIncludedFromDisk() throws Exception { CommitGraph cg = gcPack.getCommitGraph(reader); assertNotNull(cg); - assertTrue("all commits in commit graph", cg.getCommitCnt() == 3); + assertTrue("Only heads and tags reachable commits in commit graph", + cg.getCommitCnt() == 2); // GC packed assertTrue("tag referenced commit is in graph", cg.findGraphPosition(rootCommitTagged) != -1); assertTrue("head referenced commit is in graph", cg.findGraphPosition(headTip) != -1); - // GC_REST packed - assertTrue("nonHead referenced commit is in graph", - cg.findGraphPosition(nonHeadTip) != -1); + // GC_REST not in commit graph + assertEquals("nonHead referenced commit is NOT in graph", + -1, cg.findGraphPosition(nonHeadTip)); } @Test - public void produceCommitGraphAllRefsIncludedFromCache() throws Exception { + public void produceCommitGraphOnlyHeadsAndTagsIncludedFromCache() throws Exception { String tag = "refs/tags/tag1"; String head = "refs/heads/head1"; String nonHead = "refs/something/nonHead"; @@ -1043,15 +1044,16 @@ public void produceCommitGraphAllRefsIncludedFromCache() throws Exception { assertTrue("commit graph read time is recorded", reader.stats.readCommitGraphMicros > 0); - assertTrue("all commits in commit graph", cachedCG.getCommitCnt() == 3); + assertTrue("Only heads and tags reachable commits in commit graph", + cachedCG.getCommitCnt() == 2); // GC packed assertTrue("tag referenced commit is in graph", cachedCG.findGraphPosition(rootCommitTagged) != -1); assertTrue("head referenced commit is in graph", cachedCG.findGraphPosition(headTip) != -1); - // GC_REST packed - assertTrue("nonHead referenced commit is in graph", - cachedCG.findGraphPosition(nonHeadTip) != -1); + // GC_REST not in commit graph + assertEquals("nonHead referenced commit is not in graph", + -1, cachedCG.findGraphPosition(nonHeadTip)); } @Test diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java index 8cb94dcf4..774c9fadd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java @@ -783,12 +783,9 @@ private void writeCommitGraph(DfsPackDescription pack, ProgressMonitor pm) return; } - Set allTips = refsBefore.stream().map(Ref::getObjectId) - .collect(Collectors.toUnmodifiableSet()); - try (DfsOutputStream out = objdb.writeFile(pack, COMMIT_GRAPH); RevWalk pool = new RevWalk(ctx)) { - GraphCommits gcs = GraphCommits.fromWalk(pm, allTips, pool); + GraphCommits gcs = GraphCommits.fromWalk(pm, allHeadsAndTags, pool); CountingOutputStream cnt = new CountingOutputStream(out); CommitGraphWriter writer = new CommitGraphWriter(gcs, writeBloomFilter); From 551ca93cc6d45b5cbcc0066004ffcebc7cb9d7a6 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Thu, 17 Aug 2023 15:41:02 -0700 Subject: [PATCH 03/17] DfsGarbageCollector: provide commit graph stats Provide commit graph stats in the same way that we provide reftable stats. Signed-off-by: Jonathan Tan Change-Id: Ib80c892a26f9b552bc90f3cbe7da83b02ffebdfd --- .../storage/dfs/DfsGarbageCollectorTest.java | 24 +++++++++++++++++++ .../storage/dfs/DfsGarbageCollector.java | 4 ++-- .../storage/dfs/DfsPackDescription.java | 15 ++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java index 16c34500a..05360dc05 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java @@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit; import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph; +import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.reftable.RefCursor; import org.eclipse.jgit.internal.storage.reftable.ReftableConfig; @@ -1103,6 +1104,22 @@ public void commitGraphWithoutGCrestPack() throws Exception { } } + @Test + public void produceCommitGraphAndBloomFilter() throws Exception { + String head = "refs/heads/head1"; + + git.branch(head).commit().message("0").noParents().create(); + + gcWithCommitGraphAndBloomFilter(); + + assertEquals(1, odb.getPacks().length); + DfsPackFile pack = odb.getPacks()[0]; + DfsPackDescription desc = pack.getPackDescription(); + CommitGraphWriter.Stats stats = desc.getCommitGraphStats(); + assertNotNull(stats); + assertEquals(1, stats.getChangedPathFiltersComputed()); + } + @Test public void objectSizeIdx_reachableBlob_bigEnough_indexed() throws Exception { String master = "refs/heads/master"; @@ -1177,6 +1194,13 @@ private void gcWithCommitGraph() throws IOException { run(gc); } + private void gcWithCommitGraphAndBloomFilter() throws IOException { + DfsGarbageCollector gc = new DfsGarbageCollector(repo); + gc.setWriteCommitGraph(true); + gc.setWriteBloomFilter(true); + run(gc); + } + private void gcWithObjectSizeIndex(int threshold) throws IOException { DfsGarbageCollector gc = new DfsGarbageCollector(repo); gc.getPackConfig().setMinBytesForObjSizeIndex(threshold); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java index 774c9fadd..62b55d473 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java @@ -36,7 +36,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter; @@ -789,10 +788,11 @@ private void writeCommitGraph(DfsPackDescription pack, ProgressMonitor pm) CountingOutputStream cnt = new CountingOutputStream(out); CommitGraphWriter writer = new CommitGraphWriter(gcs, writeBloomFilter); - writer.write(pm, cnt); + CommitGraphWriter.Stats stats = writer.write(pm, cnt); pack.addFileExt(COMMIT_GRAPH); pack.setFileSize(COMMIT_GRAPH, cnt.getCount()); pack.setBlockSize(COMMIT_GRAPH, out.blockSize()); + pack.setCommitGraphStats(stats); } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java index f012b8bca..663190a23 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java @@ -17,6 +17,7 @@ import java.util.Comparator; import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.reftable.ReftableWriter; @@ -144,6 +145,7 @@ static Comparator reuseComparator() { private PackStatistics packStats; private ReftableWriter.Stats refStats; + private CommitGraphWriter.Stats commitGraphStats; private int extensions; private int indexVersion; private long estimatedPackSize; @@ -480,6 +482,19 @@ void setReftableStats(ReftableWriter.Stats stats) { setBlockSize(REFTABLE, stats.refBlockSize()); } + /** + * Get stats from the sibling commit graph, if created. + * + * @return stats from the sibling commit graph, if created. + */ + public CommitGraphWriter.Stats getCommitGraphStats() { + return commitGraphStats; + } + + void setCommitGraphStats(CommitGraphWriter.Stats stats) { + this.commitGraphStats = stats; + } + /** * Discard the pack statistics, if it was populated. * From 9919a9faaf9865ff799c657eb77dd8014d410b40 Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Fri, 18 Aug 2023 11:22:35 -0700 Subject: [PATCH 04/17] DfsReader: Make PackLoadListener interface visible to subclasses A subclass cannot implement a listener with the default access. Make the interface protected. Not public because so far only subclasses are interested in this interface. We can widen the visibility later if needed. Change-Id: I54e5c0ef1312dfe2fa660bc8fb54e2be35c0f6df --- .../org/eclipse/jgit/internal/storage/dfs/DfsReader.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java index 16344068e..3f0adcba1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java @@ -839,7 +839,7 @@ public DfsReaderIoStats getIoStats() { } /** Announces when data is loaded by reader */ - interface PackLoadListener { + protected interface PackLoadListener { /** * Immutable copy of a DFS block metadata */ @@ -856,11 +856,11 @@ private DfsBlockData(DfsBlock src) { this.size = src.size(); } - int getIdentityHash() { + public int getIdentityHash() { return identityHash; } - int getSize() { + public int getSize() { return size; } } @@ -900,7 +900,7 @@ void onIndexLoad(String packName, PackSource src, PackExt ext, long size, * @param ext * Extension in the pack (e.g. PACK or REFTABLE) * @param position - * Block offset being loaded + * Offset in the file requested by caller * @param dfsBlockData * Metadata of the block */ From e7a09e316dbbfff5d23cbb9687f7b0a5d44e7da0 Mon Sep 17 00:00:00 2001 From: Martin Fick Date: Mon, 14 Aug 2023 21:48:55 -0600 Subject: [PATCH 05/17] Introduce core.packedIndexGitUseStrongRefs config key Introduce a core.packedIndexGitUseStrongRefs configuration key, which defaults to true so that the current behavior does not change. However, setting it to false allows soft references to be used for Pack indices instead of strong references so that they can be garbage collected when there is memory pressure. Pack objects can be large when associated with pack files with large object counts, and this memory is not really accounted for or tracked by the WindowCache and it can be very substantial at times, especially with many large object count projects. A particularly problematic use case is Gerrit's ls-projects command which loads very little data in the WindowCache via ByteWindows, but ends up loading and holding many entire indices in memory, sometimes even after the ByteWindows for their Pack objects have already been garbage collected since they won't get cleared until after a new ByteWindow is loaded. By using SoftReferences, single use indices can get cleared when there is memory pressure and OOMs can be easily avoided, drastically reducing the amount of memory required to perform an ls-projects on large sites with many projects and large object counts. On one of our test sites, an ls-projects command with strong index references requires more than 66GB of heap to complete successfully, with soft index references it requires less than 23GB. Change-Id: I3cb3df52f4ce1b8c554d378807218f199077d80b Signed-off-by: Martin Fick Signed-off-by: Matthias Sohn --- Documentation/config-options.md | 1 + .../jgit/internal/storage/file/PackTest.java | 2 +- org.eclipse.jgit/META-INF/MANIFEST.MF | 1 + .../storage/file/ObjectDirectory.java | 2 +- .../jgit/internal/storage/file/Pack.java | 172 ++++++++++-------- .../internal/storage/file/PackDirectory.java | 5 +- .../internal/storage/file/WindowCache.java | 9 +- .../jgit/internal/util/Optionally.java | 126 +++++++++++++ .../org/eclipse/jgit/lib/ConfigConstants.java | 6 + .../jgit/storage/file/WindowCacheConfig.java | 31 ++++ 10 files changed, 274 insertions(+), 81 deletions(-) create mode 100644 org.eclipse.jgit/src/org/eclipse/jgit/internal/util/Optionally.java diff --git a/Documentation/config-options.md b/Documentation/config-options.md index 3495813e7..5651001bc 100644 --- a/Documentation/config-options.md +++ b/Documentation/config-options.md @@ -38,6 +38,7 @@ For details on native git options see also the official [git config documentatio | `core.packedGitMmap` | `false` | ✅ | Whether to use Java NIO virtual memory mapping for JGit buffer cache. When set to `true` enables use of Java NIO virtual memory mapping for cache windows, `false` reads entire window into a `byte[]` with standard read calls. `true` is experimental and may cause instabilities and crashes since Java doesn't support explicit unmapping of file regions mapped to virtual memory. | | `core.packedGitOpenFiles` | `128` | ⃞ | Maximum number of streams to open at a time. Open packs count against the process limits. | | `core.packedGitUseStrongRefs` | `false` | ⃞ | Whether the window cache should use strong references (`true`) or SoftReferences (`false`). When `false` the JVM will drop data cached in the JGit block cache when heap usage comes close to the maximum heap size. | +| `core.packedIndexGitUseStrongRefs` | `true` | ⃞ | Whether pack indices should use strong references (`true`) or SoftReferences (`false`). When `false` the JVM will drop data cached in the JGit pack indices when heap usage comes close to the maximum heap size. | | `core.packedGitWindowSize` | `8 kiB` | ✅ | Number of bytes of a pack file to load into memory in a single read operation. This is the "page size" of the JGit buffer cache, used for all pack access operations. All disk IO occurs as single window reads. Setting this too large may cause the process to load more data than is required; setting this too small may increase the frequency of read() system calls. | | `core.precomposeUnicode` | `true` on Mac OS | ✅ | MacOS only. When `true`, JGit reverts the unicode decomposition of filenames done by Mac OS. | | `core.quotePath` | `true` | ✅ | Commands that output paths (e.g. ls-files, diff), will quote "unusual" characters in the pathname by enclosing the pathname in double-quotes and escaping those characters with backslashes in the same way C escapes control characters (e.g. `\t` for TAB, `\n` for LF, `\\` for backslash) or bytes with values larger than `0x80` (e.g. octal `\302\265` for "micro" in UTF-8). | diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java index a3596541f..e1509456e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java @@ -261,7 +261,7 @@ public void testDelta_FailsOver2GiB() throws Exception { new PackIndexWriterV1(f).write(list, footer); } - Pack pack = new Pack(packName, null); + Pack pack = new Pack(repo.getConfig(), packName, null); try { pack.get(wc, b); fail("expected LargeObjectException.ExceedsByteArrayLimit"); diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index 84b2987a9..0b5e8bf16 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF @@ -124,6 +124,7 @@ Export-Package: org.eclipse.jgit.annotations;version="6.7.0", x-friends:="org.eclipse.jgit.ssh.apache, org.eclipse.jgit.ssh.jsch, org.eclipse.jgit.test", + org.eclipse.jgit.internal.util;version="6.7.0";x-internal:=true, org.eclipse.jgit.lib;version="6.7.0"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util.sha1, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java index 0ef38db31..579f93179 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java @@ -259,7 +259,7 @@ public Pack openPack(File pack) throws IOException { } PackFile bitmapIdx = pf.create(BITMAP_INDEX); - Pack res = new Pack(pack, bitmapIdx.exists() ? bitmapIdx : null); + Pack res = new Pack(config, pack, bitmapIdx.exists() ? bitmapIdx : null); packed.insert(res); return res; } 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 2b5586a2c..90f981167 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 @@ -15,6 +15,8 @@ import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX; import static org.eclipse.jgit.internal.storage.pack.PackExt.KEEP; import static org.eclipse.jgit.internal.storage.pack.PackExt.REVERSE_INDEX; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS; import java.io.EOFException; import java.io.File; @@ -32,6 +34,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Iterator; +import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.CRC32; @@ -53,8 +56,10 @@ import org.eclipse.jgit.internal.storage.pack.BinaryDelta; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.pack.PackOutputStream; +import org.eclipse.jgit.internal.util.Optionally; import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; @@ -79,6 +84,8 @@ public class Pack implements Iterable { public static final Comparator SORT = (a, b) -> b.packLastModified .compareTo(a.packLastModified); + private boolean useStrongRefs; + private final PackFile packFile; private PackFile keepFile; @@ -111,11 +118,11 @@ public class Pack implements Iterable { private byte[] packChecksum; - private volatile PackIndex loadedIdx; + private volatile Optionally loadedIdx = Optionally.empty(); - private PackReverseIndex reverseIdx; + private Optionally reverseIdx = Optionally.empty(); - private PackBitmapIndex bitmapIdx; + private Optionally bitmapIdx = Optionally.empty(); /** * Objects we have tried to read, and discovered to be corrupt. @@ -129,12 +136,16 @@ public class Pack implements Iterable { /** * Construct a reader for an existing, pre-indexed packfile. * + * @param cfg + * configuration this directory consults for write settings. * @param packFile * path of the .pack file holding the data. * @param bitmapIdxFile * existing bitmap index file with the same base as the pack */ - public Pack(File packFile, @Nullable PackFile bitmapIdxFile) { + public Pack(Config cfg, File packFile, @Nullable PackFile bitmapIdxFile) { + useStrongRefs = cfg.getBoolean(CONFIG_CORE_SECTION, + CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS, WindowCache.getInstance().isPackedIndexGitUseStrongRefs()); this.packFile = new PackFile(packFile); this.fileSnapshot = PackFileSnapshot.save(packFile); this.packLastModified = fileSnapshot.lastModifiedInstant(); @@ -148,57 +159,58 @@ public Pack(File packFile, @Nullable PackFile bitmapIdxFile) { } private PackIndex idx() throws IOException { - PackIndex idx = loadedIdx; - if (idx == null) { - synchronized (this) { - idx = loadedIdx; - if (idx == null) { - if (invalid) { - throw new PackInvalidException(packFile, - invalidatingCause); - } - try { - long start = System.currentTimeMillis(); - PackFile idxFile = packFile.create(INDEX); - idx = PackIndex.open(idxFile); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format( - "Opening pack index %s, size %.3f MB took %d ms", //$NON-NLS-1$ - idxFile.getAbsolutePath(), - Float.valueOf(idxFile.length() - / (1024f * 1024)), - Long.valueOf(System.currentTimeMillis() - - start))); - } - - if (packChecksum == null) { - packChecksum = idx.packChecksum; - fileSnapshot.setChecksum( - ObjectId.fromRaw(packChecksum)); - } else if (!Arrays.equals(packChecksum, - idx.packChecksum)) { - throw new PackMismatchException(MessageFormat - .format(JGitText.get().packChecksumMismatch, - packFile.getPath(), - PackExt.PACK.getExtension(), - Hex.toHexString(packChecksum), - PackExt.INDEX.getExtension(), - Hex.toHexString(idx.packChecksum))); - } - loadedIdx = idx; - } catch (InterruptedIOException e) { - // don't invalidate the pack, we are interrupted from - // another thread - throw e; - } catch (IOException e) { - invalid = true; - invalidatingCause = e; - throw e; - } + Optional optional = loadedIdx.getOptional(); + if (optional.isPresent()) { + return optional.get(); + } + synchronized (this) { + optional = loadedIdx.getOptional(); + if (optional.isPresent()) { + return optional.get(); + } + if (invalid) { + throw new PackInvalidException(packFile, invalidatingCause); + } + try { + long start = System.currentTimeMillis(); + PackFile idxFile = packFile.create(INDEX); + PackIndex idx = PackIndex.open(idxFile); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format( + "Opening pack index %s, size %.3f MB took %d ms", //$NON-NLS-1$ + idxFile.getAbsolutePath(), + Float.valueOf(idxFile.length() + / (1024f * 1024)), + Long.valueOf(System.currentTimeMillis() + - start))); } + + if (packChecksum == null) { + packChecksum = idx.packChecksum; + fileSnapshot.setChecksum( + ObjectId.fromRaw(packChecksum)); + } else if (!Arrays.equals(packChecksum, + idx.packChecksum)) { + throw new PackMismatchException(MessageFormat + .format(JGitText.get().packChecksumMismatch, + packFile.getPath(), + PackExt.PACK.getExtension(), + Hex.toHexString(packChecksum), + PackExt.INDEX.getExtension(), + Hex.toHexString(idx.packChecksum))); + } + loadedIdx = optionally(idx); + return idx; + } catch (InterruptedIOException e) { + // don't invalidate the pack, we are interrupted from + // another thread + throw e; + } catch (IOException e) { + invalid = true; + invalidatingCause = e; + throw e; } } - return idx; } /** * Get the File object which locates this pack on disk. @@ -288,8 +300,9 @@ void resolve(Set matches, AbbreviatedObjectId id, int matchLimit) public void close() { WindowCache.purge(this); synchronized (this) { - loadedIdx = null; - reverseIdx = null; + loadedIdx.clear(); + reverseIdx.clear(); + bitmapIdx.clear(); } } @@ -1127,40 +1140,41 @@ synchronized PackBitmapIndex getBitmapIndex() throws IOException { if (invalid || bitmapIdxFile == null) { return null; } - if (bitmapIdx == null) { - final PackBitmapIndex idx; - try { - idx = PackBitmapIndex.open(bitmapIdxFile, idx(), - getReverseIdx()); - } catch (FileNotFoundException e) { - // Once upon a time this bitmap file existed. Now it - // has been removed. Most likely an external gc has - // removed this packfile and the bitmap - bitmapIdxFile = null; - return null; - } - + Optional optional = bitmapIdx.getOptional(); + if (optional.isPresent()) { + return optional.get(); + } + try { + PackBitmapIndex idx = PackBitmapIndex.open(bitmapIdxFile, idx(), + getReverseIdx()); // At this point, idx() will have set packChecksum. if (Arrays.equals(packChecksum, idx.packChecksum)) { - bitmapIdx = idx; - } else { - bitmapIdxFile = null; + bitmapIdx = optionally(idx); + return idx; } + } catch (FileNotFoundException e) { + // Once upon a time this bitmap file existed. Now it + // has been removed. Most likely an external gc has + // removed this packfile and the bitmap } - return bitmapIdx; + bitmapIdxFile = null; + return null; } private synchronized PackReverseIndex getReverseIdx() throws IOException { if (invalid) { throw new PackInvalidException(packFile, invalidatingCause); } - if (reverseIdx == null) { - PackFile reverseIndexFile = packFile.create(REVERSE_INDEX); - reverseIdx = PackReverseIndexFactory.openOrCompute(reverseIndexFile, - getObjectCount(), () -> getIndex()); - reverseIdx.verifyPackChecksum(getPackFile().getPath()); + Optional optional = reverseIdx.getOptional(); + if (optional.isPresent()) { + return optional.get(); } - return reverseIdx; + PackFile reverseIndexFile = packFile.create(REVERSE_INDEX); + PackReverseIndex revIdx = PackReverseIndexFactory.openOrCompute(reverseIndexFile, + getObjectCount(), () -> getIndex()); + revIdx.verifyPackChecksum(getPackFile().getPath()); + reverseIdx = optionally(revIdx); + return revIdx; } private boolean isCorrupt(long offset) { @@ -1195,4 +1209,8 @@ public String toString() { + packFile.length() + ", packChecksum=" + ObjectId.fromRaw(packChecksum).name() + "]"; } + + private Optionally optionally(T element) { + return useStrongRefs ? new Optionally.Hard<>(element) : new Optionally.Soft<>(element); + } } 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 85b2d34a9..28f6250a2 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 @@ -65,6 +65,8 @@ class PackDirectory { private static final PackList NO_PACKS = new PackList(FileSnapshot.DIRTY, new Pack[0]); + private final Config config; + private final File directory; private final AtomicReference packList; @@ -80,6 +82,7 @@ class PackDirectory { * the location of the {@code pack} directory. */ PackDirectory(Config config, File directory) { + this.config = config; this.directory = directory; packList = new AtomicReference<>(NO_PACKS); @@ -457,7 +460,7 @@ private PackList scanPacksImpl(PackList old) { continue; } - list.add(new Pack(packFile, packFilesByExt.get(BITMAP_INDEX))); + list.add(new Pack(config, packFile, packFilesByExt.get(BITMAP_INDEX))); foundNew = true; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java index 25653b3ce..81537dd46 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java @@ -435,7 +435,9 @@ static final void purge(Pack pack) { private final AtomicBoolean publishMBean = new AtomicBoolean(); - private boolean useStrongRefs; + private final boolean useStrongRefs; + + private final boolean useStrongIndexRefs; private WindowCache(WindowCacheConfig cfg) { tableSize = tableSize(cfg); @@ -467,6 +469,7 @@ else if (eb < 4) windowSizeShift = bits(cfg.getPackedGitWindowSize()); windowSize = 1 << windowSizeShift; useStrongRefs = cfg.isPackedGitUseStrongRefs(); + useStrongIndexRefs = cfg.isPackedIndexGitUseStrongRefs(); queue = useStrongRefs ? new StrongCleanupQueue(this) : new SoftCleanupQueue(this); @@ -751,6 +754,10 @@ private static Entry clean(Entry top) { return n == top.next ? top : new Entry(n, top.ref); } + boolean isPackedIndexGitUseStrongRefs() { + return useStrongIndexRefs; + } + private static class Entry { /** Next entry in the hash table's chain list. */ final Entry next; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/util/Optionally.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/util/Optionally.java new file mode 100644 index 000000000..987584f64 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/util/Optionally.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. + * and other copyright owners as documented in the project's IP log. + * + * 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.internal.util; + +import java.lang.ref.SoftReference; +import java.util.Optional; + +/** + * Interface representing a reference to a potentially mutable optional object. + * + * @param + * type of the mutable optional object + * + * @since 6.7 + */ +public interface Optionally { + /** + * A permanently empty Optionally + * + * @param + * type of the mutable optional object + * + */ + public class Empty implements Optionally { + @Override + public void clear() { + // empty + } + + @Override + public Optional getOptional() { + return Optional.empty(); + } + } + + /** + * A permanent(hard) reference to an object + * + * @param + * type of the mutable optional object + * + */ + public class Hard implements Optionally { + /** + * The mutable optional object + */ + protected T element; + + /** + * @param element + * the mutable optional object + */ + public Hard(T element) { + this.element = element; + } + + @Override + public void clear() { + element = null; + } + + @Override + public Optional getOptional() { + return Optional.ofNullable(element); + } + } + + /** + * A SoftReference Optionally + * + * @param + * type of the mutable optional object + * + */ + public class Soft extends SoftReference implements Optionally { + /** + * @param t + * the mutable optional object + */ + public Soft(T t) { + super(t); + } + + @Override + public Optional getOptional() { + return Optional.ofNullable(get()); + } + } + + /** + * The empty Optionally + */ + public static final Optionally EMPTY = new Empty<>(); + + /** + * @param + * type of the empty Optionally + * @return the empty Optionally + */ + @SuppressWarnings("unchecked") + public static Optionally empty() { + return (Optionally) EMPTY; + } + + /** + * Clear the object + * + */ + void clear(); + + /** + * Get an Optional representing the current state of the object + * + * @return the mutable optional object + */ + Optional getOptional(); +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java index 7776b0062..d812eacb6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java @@ -364,6 +364,12 @@ public final class ConfigConstants { */ public static final String CONFIG_KEY_PACKED_GIT_USE_STRONGREFS = "packedgitusestrongrefs"; + /** + * The "packedIndexGitUseStrongRefs" key + * @since 6.7 + */ + public static final String CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS = "packedindexgitusestrongrefs"; + /** The "remote" key */ public static final String CONFIG_KEY_REMOTE = "remote"; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java index a12f65259..27795ab96 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java @@ -18,6 +18,7 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_WINDOWSIZE; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_STREAM_FILE_TRESHOLD; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_USE_STRONGREFS; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS; import org.eclipse.jgit.internal.storage.file.WindowCache; import org.eclipse.jgit.lib.Config; @@ -39,6 +40,8 @@ public class WindowCacheConfig { private boolean useStrongRefs; + private boolean useStrongIndexRefs; + private int packedGitWindowSize; private boolean packedGitMMAP; @@ -56,6 +59,7 @@ public WindowCacheConfig() { packedGitOpenFiles = 128; packedGitLimit = 10 * MB; useStrongRefs = false; + useStrongIndexRefs = true; packedGitWindowSize = 8 * KB; packedGitMMAP = false; deltaBaseCacheLimit = 10 * MB; @@ -132,6 +136,31 @@ public void setPackedGitUseStrongRefs(boolean useStrongRefs) { this.useStrongRefs = useStrongRefs; } + /** + * Get whether the Pack indices cache should use strong references or + * SoftReferences + * + * @return {@code true} if the cached Pack indices should use strong references, + * otherwise it will use {@link java.lang.ref.SoftReference}s + * @since 6.7 + */ + public boolean isPackedIndexGitUseStrongRefs() { + return useStrongIndexRefs; + } + + /** + * Set if the Pack indices cache should use strong refs or soft refs + * + * @param useStrongRefs + * if @{code true} the Pack strongly references cached indices + * otherwise it uses {@link java.lang.ref.SoftReference}s which + * can be evicted by the Java gc if heap is almost full + * @since 6.7 + */ + public void setPackedIndexGitUseStrongRefs(boolean useStrongRefs) { + this.useStrongIndexRefs = useStrongRefs; + } + /** * Get size in bytes of a single window mapped or read in from the pack * file. @@ -270,6 +299,8 @@ public WindowCacheConfig fromConfig(Config rc) { setPackedGitUseStrongRefs(rc.getBoolean(CONFIG_CORE_SECTION, CONFIG_KEY_PACKED_GIT_USE_STRONGREFS, isPackedGitUseStrongRefs())); + setPackedIndexGitUseStrongRefs(rc.getBoolean(CONFIG_CORE_SECTION, + CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS, isPackedIndexGitUseStrongRefs())); setPackedGitOpenFiles(rc.getInt(CONFIG_CORE_SECTION, null, CONFIG_KEY_PACKED_GIT_OPENFILES, getPackedGitOpenFiles())); setPackedGitLimit(rc.getLong(CONFIG_CORE_SECTION, null, From a56930723f85562ab47d72c9ae525c5fe4322900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Kubitz?= Date: Wed, 16 Aug 2023 14:39:23 +0200 Subject: [PATCH 06/17] ReadChangedPathFilter: fix Non-externalized string literal warning Change-Id: I78161a2dbc08918267bc59a1ed267c5108f5c391 --- .../src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java index 6927de84e..1414165e5 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java @@ -62,9 +62,9 @@ static HashSet changedPathStrings(byte[] data) { HashSet changed_paths = new HashSet<>(); for (int i = 0; i < commit_count; i++) { int prior_cumul = i == 0 ? 0 : changed_path_length_cumuls[i - 1]; - String changed_path = ""; + String changed_path = ""; //$NON-NLS-1$ for (int j = prior_cumul; j < changed_path_length_cumuls[i]; j++) { - changed_path += data[bdat_offset + j] + ","; + changed_path += data[bdat_offset + j] + ","; //$NON-NLS-1$ } changed_paths.add(changed_path); } From 055a7c20e028c4444df7983b5654f41d49501a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Kubitz?= Date: Wed, 16 Aug 2023 14:51:35 +0200 Subject: [PATCH 07/17] org.eclipse.jgit.junit.ssh/.settings/.api_filters: fix unclosed tags error was introduced with I0fb77bb9b498d48d5da88a93486b99bf8121e3bd Change-Id: I60af78cf0213a07356cb39b5f756679c58daee56 --- org.eclipse.jgit.junit.ssh/.settings/.api_filters | 2 ++ 1 file changed, 2 insertions(+) diff --git a/org.eclipse.jgit.junit.ssh/.settings/.api_filters b/org.eclipse.jgit.junit.ssh/.settings/.api_filters index 44c9dfae4..796b64170 100644 --- a/org.eclipse.jgit.junit.ssh/.settings/.api_filters +++ b/org.eclipse.jgit.junit.ssh/.settings/.api_filters @@ -5,6 +5,8 @@ + + From 0d5e0176127e273ba583fbdcd81826fc5053fbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Kubitz?= Date: Thu, 17 Aug 2023 11:20:13 +0200 Subject: [PATCH 08/17] IO: use JDK convenience methods The benefit is that certain InputStreams can override the default implementation for performance reasons. Change-Id: I4c924157ec0f0ec63b0eca7cdbdc9325af24cab6 --- .../src/org/eclipse/jgit/util/IO.java | 86 ++----------------- 1 file changed, 9 insertions(+), 77 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java index 80877bbdc..8cc531627 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java @@ -66,19 +66,7 @@ public static final byte[] readFully(File path) public static final byte[] readSome(File path, int limit) throws FileNotFoundException, IOException { try (SilentFileInputStream in = new SilentFileInputStream(path)) { - byte[] buf = new byte[limit]; - int cnt = 0; - for (;;) { - int n = in.read(buf, cnt, buf.length - cnt); - if (n <= 0) - break; - cnt += n; - } - if (cnt == buf.length) - return buf; - byte[] res = new byte[cnt]; - System.arraycopy(buf, 0, res, 0, cnt); - return res; + return in.readNBytes(limit); } } @@ -99,37 +87,10 @@ public static final byte[] readSome(File path, int limit) public static final byte[] readFully(File path, int max) throws FileNotFoundException, IOException { try (SilentFileInputStream in = new SilentFileInputStream(path)) { - long sz = Math.max(path.length(), 1); - if (sz > max) + byte[] buf = in.readNBytes(max); + if (in.read() != -1) { throw new IOException(MessageFormat.format( JGitText.get().fileIsTooLarge, path)); - - byte[] buf = new byte[(int) sz]; - int valid = 0; - for (;;) { - if (buf.length == valid) { - if (buf.length == max) { - int next = in.read(); - if (next < 0) - break; - - throw new IOException(MessageFormat.format( - JGitText.get().fileIsTooLarge, path)); - } - - byte[] nb = new byte[Math.min(buf.length * 2, max)]; - System.arraycopy(buf, 0, nb, 0, valid); - buf = nb; - } - int n = in.read(buf, valid, buf.length - valid); - if (n < 0) - break; - valid += n; - } - if (valid < buf.length) { - byte[] nb = new byte[valid]; - System.arraycopy(buf, 0, nb, 0, valid); - buf = nb; } return buf; } @@ -157,26 +118,7 @@ public static final byte[] readFully(File path, int max) */ public static ByteBuffer readWholeStream(InputStream in, int sizeHint) throws IOException { - byte[] out = new byte[sizeHint]; - int pos = 0; - while (pos < out.length) { - int read = in.read(out, pos, out.length - pos); - if (read < 0) - return ByteBuffer.wrap(out, 0, pos); - pos += read; - } - - int last = in.read(); - if (last < 0) - return ByteBuffer.wrap(out, 0, pos); - - try (TemporaryBuffer.Heap tmp = new TemporaryBuffer.Heap( - Integer.MAX_VALUE)) { - tmp.write(out); - tmp.write(last); - tmp.copy(in); - return ByteBuffer.wrap(tmp.toByteArray()); - } + return ByteBuffer.wrap(in.readAllBytes()); } /** @@ -197,13 +139,9 @@ public static ByteBuffer readWholeStream(InputStream in, int sizeHint) */ public static void readFully(final InputStream fd, final byte[] dst, int off, int len) throws IOException { - while (len > 0) { - final int r = fd.read(dst, off, len); - if (r <= 0) - throw new EOFException(JGitText.get().shortReadOfBlock); - off += r; - len -= r; - } + int read = fd.readNBytes(dst, off, len); + if (read != len) + throw new EOFException(JGitText.get().shortReadOfBlock); } /** @@ -271,14 +209,7 @@ public static int read(ReadableByteChannel channel, byte[] dst, int off, */ public static int readFully(InputStream fd, byte[] dst, int off) throws IOException { - int r; - int len = 0; - while (off < dst.length - && (r = fd.read(dst, off, dst.length - off)) >= 0) { - off += r; - len += r; - } - return len; + return fd.readNBytes(dst, off, dst.length - off); } /** @@ -300,6 +231,7 @@ public static int readFully(InputStream fd, byte[] dst, int off) */ public static void skipFully(InputStream fd, long toSkip) throws IOException { + // same as fd.skipNBytes(toSkip) of JDK 12; while (toSkip > 0) { final long r = fd.skip(toSkip); if (r <= 0) From a2f326b76200c8def03eb136811c2cb5bc304f89 Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Wed, 5 Jul 2023 22:21:30 +0200 Subject: [PATCH 09/17] Handle global git config $XDG_CONFIG_HOME/git/config C git uses this alternate fallback location if the file exists and ~/.gitconfig does not. Implement this also for JGit. If both files exist, reading behavior is as if the XDG config was inserted between the HOME config and the system config. Writing behaviour is different: all changes will be applied only in the HOME config. Updates will occur in the XDG config only if the HOME config does not exist. This is consistent with the behavior of C git; compare [1], especially the sections on FILES and SCOPES, and the description of the --global option. [1] https://git-scm.com/docs/git-config Bug: 581875 Change-Id: I2460b9aa963fd2811ed8a5b77b05107d916f2b44 Signed-off-by: Thomas Wolf --- .../jgit/storage/file/UserConfigFileTest.java | 301 ++++++++++++++++++ .../src/org/eclipse/jgit/lib/Config.java | 2 +- .../jgit/lib/DefaultTypedConfigGetter.java | 2 +- .../jgit/storage/file/FileBasedConfig.java | 20 ++ .../jgit/storage/file/UserConfigFile.java | 110 +++++++ .../org/eclipse/jgit/util/SystemReader.java | 12 +- 6 files changed, 443 insertions(+), 4 deletions(-) create mode 100644 org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java create mode 100644 org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java new file mode 100644 index 000000000..7d212d540 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2023, Thomas Wolf 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.storage.file; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.jgit.util.FS; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class UserConfigFileTest { + + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + + @Test + public void testParentOnlyLoad() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + } + + @Test + public void testLoadBoth() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + Files.writeString(user, "[user]\n\temail = a.u.thor@example.com"); + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + } + + @Test + public void testOverwriteChild() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + Files.writeString(user, "[user]\n\temail = a.u.thor@example.com"); + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + config.setString("user", null, "name", "A U Thor"); + assertEquals("A U Thor", config.getString("user", null, "name")); + config.save(); + UserConfigFile config2 = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config2.load(); + assertEquals("A U Thor", config2.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + FileBasedConfig cfg = new FileBasedConfig(null, xdg.toFile(), + FS.DETECTED); + cfg.load(); + assertEquals("Archibald Ulysses Thor", + cfg.getString("user", null, "name")); + assertNull(cfg.getString("user", null, "email")); + } + + @Test + public void testUnset() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + Files.writeString(user, "[user]\n\temail = a.u.thor@example.com"); + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + config.setString("user", null, "name", "A U Thor"); + assertEquals("A U Thor", config.getString("user", null, "name")); + config.unset("user", null, "name"); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + config.save(); + UserConfigFile config2 = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config2.load(); + assertEquals("Archibald Ulysses Thor", + config2.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + FileBasedConfig cfg = new FileBasedConfig(null, user.toFile(), + FS.DETECTED); + cfg.load(); + assertNull(cfg.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + cfg.getString("user", null, "email")); + } + + @Test + public void testUnsetSection() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + Files.writeString(user, "[user]\n\temail = a.u.thor@example.com"); + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + config.unsetSection("user", null); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + config.save(); + assertTrue(Files.readString(user).strip().isEmpty()); + } + + @Test + public void testNoChild() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertNull(config.getString("user", null, "email")); + config.setString("user", null, "email", "a.u.thor@example.com"); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + config.save(); + assertFalse(Files.exists(user)); + UserConfigFile config2 = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config2.load(); + assertEquals("Archibald Ulysses Thor", + config2.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config2.getString("user", null, "email")); + } + + @Test + public void testNoFiles() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertNull(config.getString("user", null, "name")); + assertNull(config.getString("user", null, "email")); + config.setString("user", null, "name", "Archibald Ulysses Thor"); + config.setString("user", null, "email", "a.u.thor@example.com"); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + config.save(); + assertTrue(Files.exists(user)); + assertFalse(Files.exists(xdg)); + UserConfigFile config2 = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config2.load(); + assertEquals("Archibald Ulysses Thor", + config2.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config2.getString("user", null, "email")); + } + + @Test + public void testSetInXdg() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + config.setString("user", null, "email", "a.u.thor@example.com"); + config.save(); + assertFalse(Files.exists(user)); + FileBasedConfig cfg = new FileBasedConfig(null, xdg.toFile(), + FS.DETECTED); + cfg.load(); + assertEquals("Archibald Ulysses Thor", + cfg.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + cfg.getString("user", null, "email")); + } + + @Test + public void testUserConfigCreated() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + Thread.sleep(3000); // Avoid racily clean isOutdated() below. + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + Files.writeString(user, + "[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor"); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertTrue(config.isOutdated()); + config.load(); + assertEquals("A U Thor", config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + } + + @Test + public void testUserConfigDeleted() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + Files.writeString(user, + "[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor"); + Thread.sleep(3000); // Avoid racily clean isOutdated() below. + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("A U Thor", config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + Files.delete(user); + assertEquals("A U Thor", config.getString("user", null, "name")); + assertEquals("a.u.thor@example.com", + config.getString("user", null, "email")); + assertTrue(config.isOutdated()); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertNull(config.getString("user", null, "email")); + } + + @Test + public void testXdgConfigDeleted() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + Thread.sleep(3000); // Avoid racily clean isOutdated() below. + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + Files.delete(xdg); + assertEquals("Archibald Ulysses Thor", + config.getString("user", null, "name")); + assertTrue(config.isOutdated()); + config.load(); + assertNull(config.getString("user", null, "name")); + } + + @Test + public void testXdgConfigDeletedUserConfigExists() throws Exception { + Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg"); + Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor"); + Path user = tmp.getRoot().toPath().resolve("user.cfg"); + Files.writeString(user, + "[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor"); + Thread.sleep(3000); // Avoid racily clean isOutdated() below. + UserConfigFile config = new UserConfigFile(null, user.toFile(), + xdg.toFile(), FS.DETECTED); + config.load(); + assertEquals("A U Thor", config.getString("user", null, "name")); + Files.delete(xdg); + assertTrue(config.isOutdated()); + config.load(); + assertEquals("A U Thor", config.getString("user", null, "name")); + } + +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java index 0cccaec49..7e2c5b5ad 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java @@ -739,7 +739,7 @@ protected void fireConfigChangedEvent() { listeners.dispatch(new ConfigChangedEvent()); } - String getRawString(final String section, final String subsection, + private String getRawString(final String section, final String subsection, final String name) { String[] lst = getRawStringList(section, subsection, name); if (lst != null) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java index 80aceb4e7..a71549c92 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java @@ -34,7 +34,7 @@ public class DefaultTypedConfigGetter implements TypedConfigGetter { @Override public boolean getBoolean(Config config, String section, String subsection, String name, boolean defaultValue) { - String n = config.getRawString(section, subsection, name); + String n = config.getString(section, subsection, name); if (n == null) { return defaultValue; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java index 910c5cbd8..7fdcc4d3e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java @@ -22,6 +22,8 @@ import java.io.File; import java.io.IOException; import java.text.MessageFormat; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.LockFailedException; @@ -52,6 +54,8 @@ public class FileBasedConfig extends StoredConfig { private volatile ObjectId hash; + private AtomicBoolean exists = new AtomicBoolean(); + /** * Create a configuration with no default fallback. * @@ -99,6 +103,21 @@ public final File getFile() { return configFile; } + boolean exists() { + return exists.get(); + } + + @Override + public void setStringList(String section, String subsection, String name, + List values) { + super.setStringList(section, subsection, name, values); + } + + @Override + public void unsetSection(String section, String subsection) { + super.unsetSection(section, subsection); + } + /** * {@inheritDoc} *

@@ -144,6 +163,7 @@ public void load() throws IOException, ConfigInvalidException { clear(); snapshot = lastSnapshot[0]; } + exists.set(wasRead != null); } catch (IOException e) { throw e; } catch (Exception e) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java new file mode 100644 index 000000000..2ad74c23c --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2023, Thomas Wolf 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.storage.file; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.util.FS; + +/** + * User (global) git config based on two possible locations, + * {@code ~/.gitconfig} and {@code $XDG_CONFIG_HOME/git/config}. + *

+ * For reading, both locations are considered, first the XDG file, then the file + * in the home directory. All updates occur in the last file read that exists, + * or in the home directory file if neither exists. In other words: if only the + * XDG file exists, it is updated, otherwise the home directory file is updated. + *

+ * + * @since 6.7 + */ +public class UserConfigFile extends FileBasedConfig { + + private final FileBasedConfig parent; + + /** + * Creates a new {@link UserConfigFile}. + * + * @param parent + * parent {@link Config}; may be {@code null} + * @param config + * {@link File} for {@code ~/.gitconfig} + * @param xdgConfig + * {@link File} for {@code $XDG_CONFIG_HOME/.gitconfig} + * @param fileSystem + * {@link FS} to use for the two files; normally + * {@link FS#DETECTED} + */ + public UserConfigFile(Config parent, @NonNull File config, + @NonNull File xdgConfig, @NonNull FS fileSystem) { + super(new FileBasedConfig(parent, xdgConfig, fileSystem), config, + fileSystem); + this.parent = (FileBasedConfig) getBaseConfig(); + } + + @Override + public void setStringList(String section, String subsection, String name, + List values) { + if (exists() || !parent.exists()) { + super.setStringList(section, subsection, name, values); + } else { + parent.setStringList(section, subsection, name, values); + } + } + + @Override + public void unset(String section, String subsection, String name) { + if (exists() || !parent.exists()) { + super.unset(section, subsection, name); + } else { + parent.unset(section, subsection, name); + } + } + + @Override + public void unsetSection(String section, String subsection) { + if (exists() || !parent.exists()) { + super.unsetSection(section, subsection); + } else { + parent.unsetSection(section, subsection); + } + } + + @Override + public boolean isOutdated() { + return super.isOutdated() || parent.isOutdated(); + } + + @Override + public void load() throws IOException, ConfigInvalidException { + if (super.isOutdated()) { + super.load(); + } + if (parent.isOutdated()) { + parent.load(); + } + } + + @Override + public void save() throws IOException { + if (exists() || !parent.exists()) { + if (exists() || !toText().strip().isEmpty()) { + super.save(); + } + } else { + parent.save(); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java index 991de51df..4a4876271 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java @@ -39,6 +39,7 @@ import org.eclipse.jgit.lib.ObjectChecker; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.storage.file.UserConfigFile; import org.eclipse.jgit.util.time.MonotonicClock; import org.eclipse.jgit.util.time.MonotonicSystemClock; import org.slf4j.Logger; @@ -124,8 +125,15 @@ public boolean isOutdated() { @Override public FileBasedConfig openUserConfig(Config parent, FS fs) { - return new FileBasedConfig(parent, new File(fs.userHome(), ".gitconfig"), //$NON-NLS-1$ - fs); + File homeFile = new File(fs.userHome(), ".gitconfig"); //$NON-NLS-1$ + Path xdgPath = getXdgConfigDirectory(fs); + if (xdgPath != null) { + Path configPath = xdgPath.resolve("git") //$NON-NLS-1$ + .resolve(Constants.CONFIG); + return new UserConfigFile(parent, homeFile, configPath.toFile(), + fs); + } + return new FileBasedConfig(parent, homeFile, fs); } @Override From e29834a77da41625bd48ebf0538ee016a5319b7b Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Tue, 29 Aug 2023 21:26:34 +0200 Subject: [PATCH 10/17] Fix some tests in ConfigTest Some of the ConfigTest tests created a FileRepositoryBuilder but didn't use it to actually create a FileRepository. Change-Id: I1a4b27891daee1b235a71e7bbf2a7588b9d11a53 --- .../tst/org/eclipse/jgit/lib/ConfigTest.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java index 8f9d10531..36cf77bb0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java @@ -1482,7 +1482,9 @@ public void testCommitTemplateConfig() File workTree = tmp.newFolder("dummy-worktree"); File tempFile = tmp.newFile("testCommitTemplate-"); - Repository repo = FileRepositoryBuilder.create(workTree); + Repository repo = FileRepositoryBuilder + .create(new File(workTree, ".git")); + repo.create(); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); String expectedTemplatePath = tempFile.getPath(); @@ -1532,7 +1534,9 @@ public void testCommitTemplateEncoding() throws ConfigInvalidException, IOException { Config config = new Config(null); File workTree = tmp.newFolder("dummy-worktree"); - Repository repo = FileRepositoryBuilder.create(workTree); + Repository repo = FileRepositoryBuilder + .create(new File(workTree, ".git")); + repo.create(); File tempFile = tmp.newFile("testCommitTemplate-"); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); @@ -1554,7 +1558,9 @@ public void testCommitTemplateWithInvalidEncoding() Config config = new Config(null); File workTree = tmp.newFolder("dummy-worktree"); File tempFile = tmp.newFile("testCommitTemplate-"); - Repository repo = FileRepositoryBuilder.create(workTree); + Repository repo = FileRepositoryBuilder + .create(new File(workTree, ".git")); + repo.create(); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); config = parse("[i18n]\n\tcommitEncoding = invalidEcoding\n" @@ -1569,7 +1575,9 @@ public void testCommitTemplateWithInvalidPath() Config config = new Config(null); File workTree = tmp.newFolder("dummy-worktree"); File tempFile = tmp.newFile("testCommitTemplate-"); - Repository repo = FileRepositoryBuilder.create(workTree); + Repository repo = FileRepositoryBuilder + .create(new File(workTree, ".git")); + repo.create(); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); // commit message encoding From 46264ba489b57b25f0de8013fef1c4b7306c3967 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Tue, 29 Aug 2023 22:01:03 +0200 Subject: [PATCH 11/17] Update bouncycastle to 1.76 Change-Id: Ic569f348106e917001fbaa25a302fc20cca56244 --- WORKSPACE | 18 +++++++++--------- .../org.eclipse.jgit.target/jgit-4.17.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.18.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.19.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.20.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.21.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.22.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.23.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.24.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.25.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.26.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.27.target | 10 +++++----- .../org.eclipse.jgit.target/jgit-4.28.target | 10 +++++----- .../maven/dependencies.tpd | 8 ++++---- pom.xml | 2 +- 15 files changed, 74 insertions(+), 74 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 5120ececd..d8cdde20e 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -265,32 +265,32 @@ maven_jar( src_sha1 = "135448f8b3b3b06f7f3312d222992525ae4bdd25", ) -BOUNCYCASTLE_VER = "1.75" +BOUNCYCASTLE_VER = "1.76" maven_jar( name = "bcpg", artifact = "org.bouncycastle:bcpg-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "d37fddd467bc3351e4f9a66716f5f3231a3ba540", - src_sha1 = "41b22ae4e8455f837ac65cfc618a6900ba392747", + sha1 = "d5c23d0470261254d0e84dde1d4237d228540298", + src_sha1 = "68d49cdd07da2121a904f481e2e92ca864c08d05", ) maven_jar( name = "bcprov", artifact = "org.bouncycastle:bcprov-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "fd9638f6468e934991c56242d0da2ae38890c2a4", - src_sha1 = "824c0265a84d1ec214c3513dc14fc7990bb4f70d", + sha1 = "3a785d0b41806865ad7e311162bfa3fa60b3965b", + src_sha1 = "9e00748625819d7e3cc1447366dfa76f0b354a2d", ) maven_jar( name = "bcutil", artifact = "org.bouncycastle:bcutil-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "0f58f4bbec8a40137bbb04f6174cd164fae0776b", - src_sha1 = "47713fc5d0766ab47b7dae237869ae102ed7f103", + sha1 = "8c7594e651a278bcde18e038d8ab55b1f97f4d31", + src_sha1 = "836bb2c42f10b29127b470ebe5c648927dd4ddc6", ) maven_jar( name = "bcpkix", artifact = "org.bouncycastle:bcpkix-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "5adfef8a71a0933454739264b56283cc73dd2383", - src_sha1 = "e50746007d8f1ccd9e49180af87811a1e9ce432d", + sha1 = "10c9cf5c1b4d64abeda28ee32fbade3b74373622", + src_sha1 = "e5700c1de407652c1af5961ac8a04fab02eda365", ) diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target index bf0aa3d2d..312c30248 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target index e1687627f..b212d6b82 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target index df9670f72..79b25beaa 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target index ae125365e..6e1a7f998 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target index ebd551d16..652be6491 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target index 542afa539..c881b46fa 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target index 4442d42a3..cf3d2f432 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target index 70c541b84..4ef67523c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target index 311ac4455..ad66403e9 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target index 3a8ee95a2..9c0399bbd 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target index 79537120b..055f80bfa 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target index 268a3a608..f3ab1606c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target @@ -1,7 +1,7 @@ - + @@ -201,25 +201,25 @@ org.bouncycastle bcpg-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcprov-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcpkix-jdk18on - 1.75 + 1.76 jar org.bouncycastle bcutil-jdk18on - 1.75 + 1.76 jar diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd index c9fdb6e53..918d4904c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd @@ -59,22 +59,22 @@ maven bouncycastle dependency { groupId = "org.bouncycastle" artifactId = "bcpg-jdk18on" - version = "1.75" + version = "1.76" } dependency { groupId = "org.bouncycastle" artifactId = "bcprov-jdk18on" - version = "1.75" + version = "1.76" } dependency { groupId = "org.bouncycastle" artifactId = "bcpkix-jdk18on" - version = "1.75" + version = "1.76" } dependency { groupId = "org.bouncycastle" artifactId = "bcutil-jdk18on" - version = "1.75" + version = "1.76" } } diff --git a/pom.xml b/pom.xml index bd1126007..5e95b47ac 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,7 @@ 1.7.36 3.5.0 2.10.1 - 1.75 + 1.76 4.7.3.4 3.4.3 3.3.0 From b6b0d323a71d6f36f3e752a8dfb0585768fd7c5c Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Tue, 29 Aug 2023 23:17:50 +0200 Subject: [PATCH 12/17] Update jmh to 1.37 Change-Id: I39e3dda1c13268c44055295398eab36c5ff7eb3e --- WORKSPACE | 6 +++--- org.eclipse.jgit.benchmarks/pom.xml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index d8cdde20e..021d72ccf 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -24,20 +24,20 @@ register_toolchains("//tools:error_prone_warnings_toolchain_java11_definition") register_toolchains("//tools:error_prone_warnings_toolchain_java17_definition") -JMH_VERS = "1.36" +JMH_VERS = "1.37" maven_jar( name = "jmh-core", artifact = "org.openjdk.jmh:jmh-core:" + JMH_VERS, attach_source = False, - sha1 = "5a69117788322630fc5f228bc804771335d41b1b", + sha1 = "896f27e49105b35ea1964319c83d12082e7a79ef", ) maven_jar( name = "jmh-annotations", artifact = "org.openjdk.jmh:jmh-generator-annprocess:" + JMH_VERS, attach_source = False, - sha1 = "41c92c483f92b3cce1c01edd849bfd3ffd920cf6", + sha1 = "da93888682df163144edf9b13d2b78e54166063a", ) maven_jar( diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml index e2209c7e8..fcab0a652 100644 --- a/org.eclipse.jgit.benchmarks/pom.xml +++ b/org.eclipse.jgit.benchmarks/pom.xml @@ -23,7 +23,7 @@ 11 UTF-8 - 1.36 + 1.37 benchmarks From 2d0a5fa64371679d5b9d18a48939eb22819baf83 Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Tue, 29 Aug 2023 23:22:57 +0200 Subject: [PATCH 13/17] Update tycho to 4.0.2 Change-Id: Ib619bc09bf79c0f9e7526c0303606f314e8c1209 --- org.eclipse.jgit.packaging/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 7105fb4b2..d6f669beb 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -23,7 +23,7 @@ 11 - 4.0.1 + 4.0.2 jgit-4.17 From 9fd44e0985204de7f942bf5594ab55a15c3c2fdb Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Wed, 30 Aug 2023 00:11:54 +0200 Subject: [PATCH 14/17] Use release p2 repo for Eclipse 2023-06 (4.28) Change-Id: I3b8794bdb43db12c2eacda1de27651686c41abf5 --- .../org.eclipse.jgit.target/jgit-4.28.target | 4 ++-- .../org.eclipse.jgit.target/jgit-4.28.tpd | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target index f3ab1606c..f47112fc6 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target @@ -1,7 +1,7 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd index 46185ca91..add412b69 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd @@ -3,6 +3,6 @@ target "jgit-4.28" with source configurePhase include "orbit/R20230531010532-2023-06.tpd" include "maven/dependencies.tpd" -location "https://download.eclipse.org/staging/2023-06" { +location "https://download.eclipse.org/releases/2023-06" { org.eclipse.osgi lazy } From 2a64412e946e83de51207c2af9e32343df9ecddf Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Wed, 30 Aug 2023 00:12:16 +0200 Subject: [PATCH 15/17] Add target platform for Eclipse 2023-09 (4.29) Change-Id: I62f9bacebf0a2a2cba6ffde7936572e3f05a629c --- .../org.eclipse.jgit.target/jgit-4.29.target | 270 ++++++++++++++++++ .../org.eclipse.jgit.target/jgit-4.29.tpd | 8 + 2 files changed, 278 insertions(+) create mode 100644 org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target create mode 100644 org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target new file mode 100644 index 000000000..f74fb9a43 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.tukaani + xz + 1.9 + jar + + + + + + + org.slf4j + slf4j-api + 1.7.36 + jar + + + org.slf4j + slf4j-simple + 1.7.36 + jar + + + + + + + org.apache.sshd + sshd-osgi + 2.10.0 + jar + + + org.apache.sshd + sshd-sftp + 2.10.0 + jar + + + + + + + org.mockito + mockito-core + 5.4.0 + jar + + + + + + + net.java.dev.jna + jna + 5.13.0 + jar + + + net.java.dev.jna + jna-platform + 5.13.0 + jar + + + + + + + org.eclipse.jetty + jetty-http + 10.0.15 + jar + + + org.eclipse.jetty + jetty-io + 10.0.15 + jar + + + org.eclipse.jetty + jetty-security + 10.0.15 + jar + + + org.eclipse.jetty + jetty-server + 10.0.15 + jar + + + org.eclipse.jetty + jetty-servlet + 10.0.15 + jar + + + org.eclipse.jetty + jetty-util + 10.0.15 + jar + + + org.eclipse.jetty + jetty-util-ajax + 10.0.15 + jar + + + jakarta.servlet + jakarta.servlet-api + 4.0.4 + jar + + + + + + + com.googlecode.javaewah + JavaEWAH + 1.2.3 + jar + + + + + + + org.hamcrest + hamcrest + 2.2 + jar + + + + + + + com.google.code.gson + gson + 2.10.1 + jar + + + + + + + net.bytebuddy + byte-buddy + 1.14.5 + jar + + + net.bytebuddy + byte-buddy-agent + 1.14.5 + jar + + + + + + + org.bouncycastle + bcpg-jdk18on + 1.76 + jar + + + org.bouncycastle + bcprov-jdk18on + 1.76 + jar + + + org.bouncycastle + bcpkix-jdk18on + 1.76 + jar + + + org.bouncycastle + bcutil-jdk18on + 1.76 + jar + + + + + + + org.assertj + assertj-core + 3.24.2 + jar + + + + + + + args4j + args4j + 2.33 + jar + + + + + + + commons-codec + commons-codec + 1.16.0 + jar + + + org.apache.commons + commons-compress + 1.23.0 + jar + + + commons-logging + commons-logging + 1.2 + jar + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd new file mode 100644 index 000000000..ce10ac054 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd @@ -0,0 +1,8 @@ +target "jgit-4.29" with source configurePhase + +include "orbit/R20230531010532-2023-06.tpd" +include "maven/dependencies.tpd" + +location "https://download.eclipse.org/releases/2023-09" { + org.eclipse.osgi lazy +} From 8995a64295aeb6afeccd5e70c050f395a59436eb Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Wed, 30 Aug 2023 00:36:29 +0200 Subject: [PATCH 16/17] Update Orbit to orbit-aggregation/release/4.29.0 Switch to bundle dependencies for hamcrest 1.3 to avoid issues with split packages in that version. Don't allow hamcrest 2.x yet since junit 4.13.2 still requires hamcrest 1.3. See Orbit restructuring in https://github.com/orgs/eclipse-orbit/discussions/49 Change-Id: I8faf519b8f2c4e4a6bd255d694d1aa28017acd85 --- .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 4 +-- .../org.eclipse.jgit.target/jgit-4.17.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.17.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.18.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.18.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.19.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.19.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.20.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.20.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.21.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.21.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.22.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.22.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.23.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.23.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.24.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.24.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.25.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.25.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.26.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.26.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.27.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.27.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.28.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.28.tpd | 2 +- .../org.eclipse.jgit.target/jgit-4.29.target | 29 ++++++++++--------- .../org.eclipse.jgit.target/jgit-4.29.tpd | 2 +- .../orbit/orbit-4.29.tpd | 26 +++++++++++++++++ .../META-INF/MANIFEST.MF | 2 +- .../META-INF/MANIFEST.MF | 2 +- org.eclipse.jgit.test/META-INF/MANIFEST.MF | 4 +-- 32 files changed, 241 insertions(+), 202 deletions(-) create mode 100644 org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.29.tpd diff --git a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF index f8c801bc6..ab5a071ac 100644 --- a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF @@ -7,6 +7,7 @@ Bundle-Version: 6.7.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)" Import-Package: org.bouncycastle.jce.provider;version="[1.65.0,2.0.0)", org.bouncycastle.openpgp;version="[1.65.0,2.0.0)", org.bouncycastle.openpgp.operator;version="[1.65.0,2.0.0)", @@ -15,7 +16,6 @@ Import-Package: org.bouncycastle.jce.provider;version="[1.65.0,2.0.0)", org.eclipse.jgit.gpg.bc.internal;version="[6.7.0,6.8.0)", org.eclipse.jgit.gpg.bc.internal.keys;version="[6.7.0,6.8.0)", org.eclipse.jgit.util.sha1;version="[6.7.0,6.8.0)", - org.hamcrest;version="[1.1.0,3.0.0)", org.junit;version="[4.13,5.0.0)", org.junit.runner;version="[4.13,5.0.0)", org.junit.runners;version="[4.13,5.0.0)" diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF index 859261742..2fd919eaf 100644 --- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF @@ -7,6 +7,8 @@ Bundle-Version: 6.7.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)", + org.hamcrest.library;bundle-version="[1.3.0,2.0.0)" Import-Package: javax.servlet;version="[2.5.0,5.0.0)", javax.servlet.http;version="[2.5.0,5.0.0)", org.apache.commons.codec;version="[1.6.0,2.0.0)", @@ -46,8 +48,6 @@ Import-Package: javax.servlet;version="[2.5.0,5.0.0)", org.eclipse.jgit.transport.http.apache;version="[6.7.0,6.8.0)", org.eclipse.jgit.transport.resolver;version="[6.7.0,6.8.0)", org.eclipse.jgit.util;version="[6.7.0,6.8.0)", - org.hamcrest;version="[1.1.0,3.0.0)", - org.hamcrest.core;version="[1.1.0,3.0.0)", org.junit;version="[4.13,5.0.0)", org.junit.rules;version="[4.13,5.0.0)", org.junit.runner;version="[4.13,5.0.0)", diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target index 312c30248..0e0e829ac 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd index 2560b0cb0..074ba5c44 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd @@ -1,6 +1,6 @@ target "jgit-4.17" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2020-09/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target index b212d6b82..7a02b25b8 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd index de0655fe9..79028fe0e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd @@ -1,6 +1,6 @@ target "jgit-4.18" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2020-12/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target index 79b25beaa..22a9bd892 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd index 9f1802ded..3fb1e1926 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd @@ -1,6 +1,6 @@ target "jgit-4.19-staging" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2021-03/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target index 6e1a7f998..ec90b4023 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd index 97a5e8226..ebc785730 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd @@ -1,6 +1,6 @@ target "jgit-4.20" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2021-06/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target index 652be6491..b58372246 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd index be434747b..126438d9b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd @@ -1,6 +1,6 @@ target "jgit-4.21" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2021-09/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target index c881b46fa..3c6eff5ef 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd index 2f8f60ec9..f258eeeca 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd @@ -1,6 +1,6 @@ target "jgit-4.22" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2021-12/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target index cf3d2f432..f9adacd23 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.tpd index a4a1c5287..5bdffaeaa 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.tpd @@ -1,6 +1,6 @@ target "jgit-4.23" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2022-03/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target index 4ef67523c..5811cf66e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.tpd index 980e7f99b..cd61ee022 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.tpd @@ -1,6 +1,6 @@ target "jgit-4.24" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2022-06/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target index ad66403e9..5b58e1674 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.tpd index c6f636efb..c7f159180 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.tpd @@ -1,6 +1,6 @@ target "jgit-4.25" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2022-09/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target index 9c0399bbd..9feba5391 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.tpd index 1e2c19a80..6d2fea173 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.tpd @@ -1,6 +1,6 @@ target "jgit-4.26" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2022-12/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target index 055f80bfa..dd347a185 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.tpd index bbb4baf5a..c359ccd10 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.tpd @@ -1,6 +1,6 @@ target "jgit-4.27" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2023-03/" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target index f47112fc6..1f6b65f28 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd index add412b69..814b1219c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd @@ -1,6 +1,6 @@ target "jgit-4.28" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2023-06" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target index f74fb9a43..29d6087da 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target @@ -1,7 +1,7 @@ - + @@ -12,19 +12,20 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd index ce10ac054..3318e4f2e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd @@ -1,6 +1,6 @@ target "jgit-4.29" with source configurePhase -include "orbit/R20230531010532-2023-06.tpd" +include "orbit/orbit-4.29.tpd" include "maven/dependencies.tpd" location "https://download.eclipse.org/releases/2023-09" { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.29.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.29.tpd new file mode 100644 index 000000000..1ae3a0c81 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.29.tpd @@ -0,0 +1,26 @@ +target "orbit-4.29" with source configurePhase +// see https://download.eclipse.org/tools/orbit/downloads/ + +location "https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0" { + com.jcraft.jsch [0.1.55.v20221112-0806,0.1.55.v20221112-0806] + com.jcraft.jsch.source [0.1.55.v20221112-0806,0.1.55.v20221112-0806] + com.jcraft.jzlib [1.1.3.v20220502-1820,1.1.3.v20220502-1820] + com.jcraft.jzlib.source [1.1.3.v20220502-1820,1.1.3.v20220502-1820] + net.i2p.crypto.eddsa [0.3.0.v20220506-1020,0.3.0.v20220506-1020] + net.i2p.crypto.eddsa.source [0.3.0.v20220506-1020,0.3.0.v20220506-1020] + org.apache.ant [1.10.12.v20211102-1452,1.10.12.v20211102-1452] + org.apache.ant.source [1.10.12.v20211102-1452,1.10.12.v20211102-1452] + org.apache.httpcomponents.httpclient [4.5.14,4.5.14] + org.apache.httpcomponents.httpclient.source [4.5.14,4.5.14] + org.apache.httpcomponents.httpcore [4.4.16,4.4.16] + org.apache.httpcomponents.httpcore.source [4.4.16,4.4.16] + org.hamcrest.core [1.3.0.v20230809-1000,1.3.0.v20230809-1000] + org.hamcrest.core.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000] + org.hamcrest.library [1.3.0.v20230809-1000,1.3.0.v20230809-1000] + org.hamcrest.library.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000] + org.junit [4.13.2.v20230809-1000,4.13.2.v20230809-1000] + org.junit.source [4.13.2.v20230809-1000,4.13.2.v20230809-1000] + org.objenesis [3.3,3.3] + org.objenesis.source [3.3,3.3] + org.osgi.service.cm [1.6.1.202109301733,1.6.1.202109301733] +} diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF index b347004e4..309204dd1 100644 --- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF @@ -7,6 +7,7 @@ Bundle-Version: 6.7.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)" Import-Package: org.apache.sshd.client.config.hosts;version="[2.10.0,2.11.0)", org.apache.sshd.common;version="[2.10.0,2.11.0)", org.apache.sshd.common.auth;version="[2.10.0,2.11.0)", @@ -31,7 +32,6 @@ Import-Package: org.apache.sshd.client.config.hosts;version="[2.10.0,2.11.0)", org.eclipse.jgit.transport.sshd;version="[6.7.0,6.8.0)", org.eclipse.jgit.transport.sshd.agent;version="[6.7.0,6.8.0)", org.eclipse.jgit.util;version="[6.7.0,6.8.0)", - org.hamcrest;version="[1.1.0,3.0.0)", org.junit;version="[4.13,5.0.0)", org.junit.experimental.theories;version="[4.13,5.0.0)", org.junit.runner;version="[4.13,5.0.0)" diff --git a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF index 2bd03f07b..d9d650771 100644 --- a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF @@ -7,6 +7,7 @@ Bundle-Version: 6.7.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)" Import-Package: com.jcraft.jsch;version="[0.1.54,0.2.0)", org.eclipse.jgit.errors;version="[6.7.0,6.8.0)", org.eclipse.jgit.junit;version="[6.7.0,6.8.0)", @@ -15,7 +16,6 @@ Import-Package: com.jcraft.jsch;version="[0.1.54,0.2.0)", org.eclipse.jgit.transport;version="[6.7.0,6.8.0)", org.eclipse.jgit.transport.ssh.jsch;version="[6.7.0,6.8.0)", org.eclipse.jgit.util;version="[6.7.0,6.8.0)", - org.hamcrest;version="[1.1.0,3.0.0)", org.junit;version="[4.13,5.0.0)", org.junit.experimental.theories;version="[4.13,5.0.0)", org.junit.runner;version="[4.13,5.0.0)" diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index d4d84bcd9..3ae2d6b5d 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF @@ -7,6 +7,8 @@ Bundle-Version: 6.7.0.qualifier Bundle-Localization: plugin Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)", + org.hamcrest.library;bundle-version="[1.3.0,2.0.0)" Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", net.bytebuddy.agent;version="[1.9.0,2.0.0)", net.bytebuddy.dynamic.loading;version="[1.9.0,2.0.0)", @@ -75,8 +77,6 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", org.eclipse.jgit.util;version="[6.7.0,6.8.0)", org.eclipse.jgit.util.io;version="[6.7.0,6.8.0)", org.eclipse.jgit.util.sha1;version="[6.7.0,6.8.0)", - org.hamcrest;version="[1.1.0,3.0.0)", - org.hamcrest.collection;version="[1.1.0,3.0.0)", org.junit;version="[4.13,5.0.0)", org.junit.experimental.theories;version="[4.13,5.0.0)", org.junit.function;version="[4.13.0,5.0.0)", From 2be8bf2b37177256e5183f26b7ccd13e104daf5f Mon Sep 17 00:00:00 2001 From: Matthias Sohn Date: Wed, 30 Aug 2023 14:15:27 +0200 Subject: [PATCH 17/17] Remove the cbi-snapshots Maven repository since it's not used anymore. Change-Id: I884c5e5854d6a1f5b104d8d3bb0419e860fa34ca --- org.eclipse.jgit.packaging/pom.xml | 4 ---- pom.xml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index d6f669beb..af5e4a287 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -32,10 +32,6 @@ repo.eclipse.org.cbi-releases https://repo.eclipse.org/content/repositories/cbi-releases/ - - repo.eclipse.org.cbi-snapshots - https://repo.eclipse.org/content/repositories/cbi-snapshots/ - diff --git a/pom.xml b/pom.xml index 5e95b47ac..c26d9f216 100644 --- a/pom.xml +++ b/pom.xml @@ -203,10 +203,6 @@ repo.eclipse.org.cbi-releases https://repo.eclipse.org/content/repositories/cbi-releases/ - - repo.eclipse.org.cbi-snapshots - https://repo.eclipse.org/content/repositories/cbi-snapshots/ - repo.eclipse.org.dash-releases https://repo.eclipse.org/content/repositories/dash-licenses-releases/