Merge branch 'master' into stable-6.4 * master: [benchmarks] Remove profiler configuration Add SHA1 benchmark [benchmarks] Set version of maven-compiler-plugin to 3.8.1 Fix running JMH benchmarks Add option to allow using JDK's SHA1 implementation Fix API breakage caused by extracting WorkTreeUpdater Update Orbit to S20221109014815 Use replace instead of replaceAll in toCleanString Extract Exception -> HTTP status code mapping for reuse Don't handle internal git errors as an HTTP error Fix the path for JSchText.properties Fix Maven SHA1 for Bazel build UploadPack: Receive and parse client session-id TransferConfig: Move reading advertisesid setting into TransferConfig FirstWant: Parse client session-id if received. ReceivePack: Receive and parse client session-id. Ignore IllegalStateException if JVM is already shutting down Allow to perform PackedBatchRefUpdate without locking loose refs Change-Id: Ib38376bb8fa4a64af93bf1ffb5883711eaa432d7
diff --git a/WORKSPACE b/WORKSPACE index a65b26b..c9088fc 100644 --- a/WORKSPACE +++ b/WORKSPACE
@@ -87,7 +87,7 @@ maven_jar( name = "httpcore", artifact = "org.apache.httpcomponents:httpcore:4.4.15", - sha1 = "2ab1724e80d075698903a49f5e8fa90b077937ac", + sha1 = "7f2e0c573eaa7a74bac2e89b359e1f73d92a0a1d", ) maven_jar( @@ -104,14 +104,14 @@ maven_jar( name = "jna", - artifact = "net.java.dev.jna:jna:5.8.0", - sha1 = "3551d8d827e54858214107541d3aff9c615cb615", + artifact = "net.java.dev.jna:jna:5.12.1", + sha1 = "b1e93a735caea94f503e95e6fe79bf9cdc1e985d", ) maven_jar( name = "jna-platform", - artifact = "net.java.dev.jna:jna-platform:5.8.0", - sha1 = "2f12f6d7f7652270d13624cef1b82d8cd9a5398e", + artifact = "net.java.dev.jna:jna-platform:5.12.1", + sha1 = "097406a297c852f4a41e688a176ec675f72e8329", ) maven_jar( @@ -176,8 +176,8 @@ maven_jar( name = "mockito", - artifact = "org.mockito:mockito-core:2.23.0", - sha1 = "497ddb32fd5d01f9dbe99a2ec790aeb931dff1b1", + artifact = "org.mockito:mockito-core:4.8.1", + sha1 = "d8eb9dec8747d08645347bb8c69088ac83197975", ) maven_jar( @@ -186,24 +186,24 @@ sha1 = "66f1f0ebd6db2b24e4a731979171da16ba919cd5", ) -BYTE_BUDDY_VERSION = "1.9.0" +BYTE_BUDDY_VERSION = "1.12.18" maven_jar( name = "bytebuddy", artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION, - sha1 = "8cb0d5baae526c9df46ae17693bbba302640538b", + sha1 = "875a9c3f29d2f6f499dfd60d76e97a343f9b1233", ) maven_jar( name = "bytebuddy-agent", artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION, - sha1 = "37b5703b4a6290be3fffc63ae9c6bcaaee0ff856", + sha1 = "417a7310a7bf1c1aae5ca502d26515f9c2f94396", ) maven_jar( name = "objenesis", - artifact = "org.objenesis:objenesis:2.6", - sha1 = "639033469776fd37c08358c6b92a4761feb2af4b", + artifact = "org.objenesis:objenesis:3.3", + sha1 = "1049c09f1de4331e8193e579448d0916d75b7631", ) maven_jar( @@ -263,32 +263,32 @@ src_sha1 = "f35f5525a5d30dc1237b85457d758d578e3ce8d0", ) -BOUNCYCASTLE_VER = "1.71" +BOUNCYCASTLE_VER = "1.72" maven_jar( name = "bcpg", artifact = "org.bouncycastle:bcpg-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "d42ad9fe1b89246bb4ca2a45c0646bf6f6066013", - src_sha1 = "75b8faa0a36bd27207489c06a21a1958e208034e", + sha1 = "1a36a1740d07869161f6f0d01fae8d72dd1d8320", + src_sha1 = "fe19ed35a28b345d00459de55cd20ad9e1385a4f", ) maven_jar( name = "bcprov", artifact = "org.bouncycastle:bcprov-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "943e8d0c2bd592ad78759c39d6f749fafaf29cf4", - src_sha1 = "5d398e3d54c0b8d6e24b0d929f45a89939d78f02", + sha1 = "d8dc62c28a3497d29c93fee3e71c00b27dff41b4", + src_sha1 = "308b5a8a89c29169390210b7b8e2b2534b27ff19", ) maven_jar( name = "bcutil", artifact = "org.bouncycastle:bcutil-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "57daa18bc93730eab46291d9b55a15480e013265", - src_sha1 = "2ece8feb18f69679f9b23d36007ac3b79eaf9e6d", + sha1 = "41f19a69ada3b06fa48781120d8bebe1ba955c77", + src_sha1 = "fc16dc9eb28a2ee6cbe35ecda6ec7e050ddf3cba", ) maven_jar( name = "bcpkix", artifact = "org.bouncycastle:bcpkix-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "211bcae48a96c688ca215394d631eec2b874fff1", - src_sha1 = "c72fab9b147394495a0a2858730f62b262f8a844", + sha1 = "bb3fdb5162ccd5085e8d7e57fada4d8eaa571f5a", + src_sha1 = "6fa7015a0be76b270e911bf426abf8efd1c5e42d", )
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml index 98029ab..f30d114 100644 --- a/org.eclipse.jgit.benchmarks/pom.xml +++ b/org.eclipse.jgit.benchmarks/pom.xml
@@ -37,13 +37,17 @@ <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>${jmh.version}</version> - <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.junit</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> <build>
diff --git a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/CreateFileSnapshotBenchmark.java b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/CreateFileSnapshotBenchmark.java index 97c847b..913ca5a 100644 --- a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/CreateFileSnapshotBenchmark.java +++ b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/CreateFileSnapshotBenchmark.java
@@ -69,8 +69,6 @@ public FileSnapshot testCreateFileSnapshot() { public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(CreateFileSnapshotBenchmark.class.getSimpleName()) - // .addProfiler(StackProfiler.class) - // .addProfiler(GCProfiler.class) .forks(1).jvmArgs("-ea").build(); new Runner(opt).run(); }
diff --git a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/FileMoveBenchmark.java b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/FileMoveBenchmark.java index d3ada22..2ec5f1f 100644 --- a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/FileMoveBenchmark.java +++ b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/FileMoveBenchmark.java
@@ -128,8 +128,6 @@ public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(FileMoveBenchmark.class .getSimpleName()) - // .addProfiler(StackProfiler.class) - // .addProfiler(GCProfiler.class) .forks(1).jvmArgs("-ea").build(); new Runner(opt).run(); }
diff --git a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/LookupFileStoreBenchmark.java b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/LookupFileStoreBenchmark.java index 858e2dc..393edcb 100644 --- a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/LookupFileStoreBenchmark.java +++ b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/LookupFileStoreBenchmark.java
@@ -56,8 +56,6 @@ public FileStore testLookupFileStore() throws IOException { public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(LookupFileStoreBenchmark.class.getSimpleName()) - .addProfiler(StackProfiler.class) - // .addProfiler(GCProfiler.class) .forks(1).jvmArgs("-ea").build(); new Runner(opt).run(); }
diff --git a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SHA1Benchmark.java b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SHA1Benchmark.java new file mode 100644 index 0000000..a2b5933 --- /dev/null +++ b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SHA1Benchmark.java
@@ -0,0 +1,99 @@ +/* + * Copyright (C) 2022, Matthias Sohn <matthias.sohn@sap.com> 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.benchmarks; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jgit.junit.MockSystemReader; +import org.eclipse.jgit.util.SystemReader; +import org.eclipse.jgit.util.sha1.SHA1; +import org.eclipse.jgit.util.sha1.SHA1.Sha1Implementation; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@State(Scope.Thread) +public class SHA1Benchmark { + + @State(Scope.Benchmark) + public static class BenchmarkState { + + @Param({ "1", "2", "4", "8", "16", "32", "64" }) + int size; + + @Param({ "false", "true" }) + boolean detectCollision; + + @Param({ "java", "jdkNative" }) + String impl; + + private SecureRandom rnd; + + byte[] content; + + @Setup + public void setupBenchmark() { + SystemReader.setInstance(new MockSystemReader()); + if (impl.equalsIgnoreCase(Sha1Implementation.JDKNATIVE.name())) { + System.setProperty("org.eclipse.jgit.util.sha1.implementation", + Sha1Implementation.JDKNATIVE.name()); + } + content = new byte[size * 1024]; + try { + rnd = SecureRandom.getInstanceStrong(); + } catch (NoSuchAlgorithmException e) { + // ignore + } + rnd.nextBytes(content); + } + + @TearDown + public void teardown() { + SystemReader.setInstance(null); + rnd = null; + } + } + + @Benchmark + @BenchmarkMode({ Mode.AverageTime }) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + @Warmup(iterations = 2, time = 100, timeUnit = TimeUnit.MILLISECONDS) + @Measurement(iterations = 2, time = 5, timeUnit = TimeUnit.SECONDS) + @Fork(1) + public void testSHA1(Blackhole blackhole, BenchmarkState state) { + SHA1 hash = SHA1.newInstance(); + hash.setDetectCollision(state.detectCollision); + hash.update(state.content); + blackhole.consume(hash.digest()); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(SHA1Benchmark.class.getSimpleName()) + .forks(1).jvmArgs("-ea").build(); + new Runner(opt).run(); + } +}
diff --git a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SimpleLruCacheBenchmark.java b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SimpleLruCacheBenchmark.java index 73cc1c2..caefd75 100644 --- a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SimpleLruCacheBenchmark.java +++ b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/SimpleLruCacheBenchmark.java
@@ -71,8 +71,6 @@ public SimpleLruCache<String, String> testCacheRead() { public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(SimpleLruCacheBenchmark.class.getSimpleName()) - // .addProfiler(StackProfiler.class) - // .addProfiler(GCProfiler.class) .forks(1).jvmArgs("-ea").build(); new Runner(opt).run(); }
diff --git a/org.eclipse.jgit.http.server/.settings/.api_filters b/org.eclipse.jgit.http.server/.settings/.api_filters new file mode 100644 index 0000000..2c32c98 --- /dev/null +++ b/org.eclipse.jgit.http.server/.settings/.api_filters
@@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<component id="org.eclipse.jgit.http.server" version="2"> + <resource path="src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java" type="org.eclipse.jgit.http.server.UploadPackErrorHandler"> + <filter id="1210056707"> + <message_arguments> + <message_argument value="6.1.1"/> + <message_argument value="statusCodeForThrowable(Throwable)"/> + </message_arguments> + </filter> + </resource> +</component>
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java index f1155dc..078b22a 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java
@@ -226,7 +226,8 @@ private static boolean isReceivePackSideBand(HttpServletRequest req) { // So, cheat and read the first line. String line = new PacketLineIn(req.getInputStream()).readString(); FirstCommand parsed = FirstCommand.fromLine(line); - return parsed.getCapabilities().contains(CAPABILITY_SIDE_BAND_64K); + return parsed.getCapabilities() + .containsKey(CAPABILITY_SIDE_BAND_64K); } catch (IOException e) { // Probably the connection is closed and a subsequent write will fail, but // try it just in case.
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java index 03be087..2aadbbc 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java
@@ -9,13 +9,19 @@ */ package org.eclipse.jgit.http.server; +import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; +import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; +import static javax.servlet.http.HttpServletResponse.SC_OK; + import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.transport.ServiceMayNotContinueException; import org.eclipse.jgit.transport.UploadPack; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** * Handle git-upload-pack errors. @@ -35,6 +41,24 @@ */ public interface UploadPackErrorHandler { /** + * Maps a thrown git related Exception to an appropriate HTTP status code. + * + * @param error + * The thrown Exception. + * @return the HTTP status code as an int + * @since 6.1.1 + */ + public static int statusCodeForThrowable(Throwable error) { + if (error instanceof ServiceNotEnabledException) { + return SC_FORBIDDEN; + } + if (error instanceof PackProtocolException) { + // Internal git errors are not errors from an HTTP standpoint. + return SC_OK; + } + return SC_INTERNAL_SERVER_ERROR; + } + /** * @param req * The HTTP request * @param rsp
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java index 23a398f..b0a07f1 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
@@ -10,9 +10,7 @@ package org.eclipse.jgit.http.server; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; -import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import static javax.servlet.http.HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE; import static org.eclipse.jgit.http.server.GitSmartHttpTools.UPLOAD_PACK; @@ -23,6 +21,7 @@ import static org.eclipse.jgit.http.server.ServletUtils.consumeRequestBody; import static org.eclipse.jgit.http.server.ServletUtils.getInputStream; import static org.eclipse.jgit.http.server.ServletUtils.getRepository; +import static org.eclipse.jgit.http.server.UploadPackErrorHandler.statusCodeForThrowable; import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT; import java.io.IOException; @@ -49,7 +48,6 @@ import org.eclipse.jgit.transport.ServiceMayNotContinueException; import org.eclipse.jgit.transport.UploadPack; import org.eclipse.jgit.transport.UploadPackInternalServerErrorException; -import org.eclipse.jgit.transport.WantNotValidException; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.eclipse.jgit.transport.resolver.UploadPackFactory; @@ -153,16 +151,6 @@ public void destroy() { } } - private static int statusCodeForThrowable(Throwable error) { - if (error instanceof ServiceNotEnabledException) { - return SC_FORBIDDEN; - } - if (error instanceof WantNotValidException) { - return SC_BAD_REQUEST; - } - return SC_INTERNAL_SERVER_ERROR; - } - private final UploadPackErrorHandler handler; UploadPackServlet(@Nullable UploadPackErrorHandler handler) {
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java index 8f3888e..b9b10b4 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
@@ -537,9 +537,9 @@ public void testFetchBySHA1Unreachable() throws Exception { Collections.singletonList( new RefSpec(unreachableCommit.name())))); assertTrue(e.getMessage().contains( - "Bad Request")); + "want " + unreachableCommit.name() + " not valid")); } - assertLastRequestStatusCode(400); + assertLastRequestStatusCode(200); } @Test @@ -560,9 +560,9 @@ protected Map<String, Ref> getAdvertisedRefs(Repository repository, () -> t.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(new RefSpec(A.name())))); assertTrue( - e.getMessage().contains("Bad Request")); + e.getMessage().contains("want " + A.name() + " not valid")); } - assertLastRequestStatusCode(400); + assertLastRequestStatusCode(200); } @Test @@ -1610,9 +1610,9 @@ public void testInvalidWant() throws Exception { fail("Server accepted want " + id.name()); } catch (TransportException err) { assertTrue(err.getMessage() - .contains("Bad Request")); + .contains("want " + id.name() + " not valid")); } - assertLastRequestStatusCode(400); + assertLastRequestStatusCode(200); } @Test
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 95a748e..cfdf40c 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.17" sequenceNumber="1665357434"> +<target name="jgit-4.17" sequenceNumber="1668442243"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 059f332..1f6d8b6 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,7 +1,7 @@ target "jgit-4.17" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/releases/2020-09/" { org.eclipse.osgi lazy
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 f22776c..d658228 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.18" sequenceNumber="1665357434"> +<target name="jgit-4.18" sequenceNumber="1668442243"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 54c1c91..ace8951 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,7 +1,7 @@ target "jgit-4.18" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/releases/2020-12/" { org.eclipse.osgi lazy
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 b7dc6da..752f644 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.19-staging" sequenceNumber="1665357434"> +<target name="jgit-4.19-staging" sequenceNumber="1668442242"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 e8cdc00..9eaf1a1 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,7 +1,7 @@ target "jgit-4.19-staging" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/releases/2021-03/" { org.eclipse.osgi lazy
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 3085df9..10d49f8 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.20" sequenceNumber="1665357434"> +<target name="jgit-4.20" sequenceNumber="1668442242"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 60cc123..ac083df 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,7 +1,7 @@ target "jgit-4.20" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/releases/2021-06/" { org.eclipse.osgi lazy
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 81ca92e..e4c2b69 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.21" sequenceNumber="1665357434"> +<target name="jgit-4.21" sequenceNumber="1668442241"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 3c5fddf..0f1fb8d 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,7 +1,7 @@ target "jgit-4.21" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/releases/2021-09/" { org.eclipse.osgi lazy
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 7257fcf..57bcd9a 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.22" sequenceNumber="1665357433"> +<target name="jgit-4.22" sequenceNumber="1668442241"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 70ebbad..4aae497 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,7 +1,7 @@ target "jgit-4.22" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/releases/2021-12/" { org.eclipse.osgi lazy
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 278e1f6..2a8d7cd 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.23" sequenceNumber="1665357433"> +<target name="jgit-4.23" sequenceNumber="1668442240"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 62e1b21..63f7212 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,7 +1,7 @@ target "jgit-4.23" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/releases/2022-03/" { org.eclipse.osgi lazy
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 d8f2349..9368769 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.24" sequenceNumber="1665357433"> +<target name="jgit-4.24" sequenceNumber="1668442240"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 a113eef..c033d1f 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,7 +1,7 @@ target "jgit-4.24" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/releases/2022-06/" { org.eclipse.osgi lazy
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 7386c67..a3faa8f 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 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.25" sequenceNumber="1665357420"> +<target name="jgit-4.25" sequenceNumber="1668442240"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="jakarta.servlet-api" version="4.0.0"/> @@ -29,10 +29,10 @@ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/> <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/> - <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/> - <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/> - <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/> + <unit id="com.sun.jna" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.source" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform" version="5.12.1.v20221103-2317"/> + <unit id="com.sun.jna.platform.source" version="5.12.1.v20221103-2317"/> <unit id="javaewah" version="1.1.13.v20211029-0839"/> <unit id="javaewah.source" version="1.1.13.v20211029-0839"/> <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> @@ -59,14 +59,14 @@ <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/> <unit id="org.assertj" version="3.20.2.v20210706-1104"/> <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/> - <unit id="org.bouncycastle.bcpg" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpg.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcprov.source" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil" version="1.71.0.v20220723-1943"/> - <unit id="org.bouncycastle.bcutil.source" version="1.71.0.v20220723-1943"/> + <unit id="org.bouncycastle.bcpg" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpg.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcprov.source" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil" version="1.72.0.v20221013-1810"/> + <unit id="org.bouncycastle.bcutil.source" version="1.72.0.v20221013-1810"/> <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/> <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> @@ -77,17 +77,17 @@ <unit id="org.junit.source" version="4.13.2.v20211018-1956"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> - <unit id="org.mockito" version="2.23.0.v20200310-1642"/> - <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> - <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> - <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/> + <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/> + <unit id="org.objenesis" version="3.3.0.v20221103-2317"/> + <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/> <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/> <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/> <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/> <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/>
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 c0bce96..e0fb34e 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,7 +1,7 @@ target "jgit-4.25" with source configurePhase include "projects/jetty-10.0.x.tpd" -include "orbit/S20220927175816.tpd" +include "orbit/S20221109014815.tpd" location "https://download.eclipse.org/staging/2022-09/" { org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20220927175816.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20221109014815.tpd similarity index 74% rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20220927175816.tpd rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20221109014815.tpd index 4d9c638..0c0520b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20220927175816.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20221109014815.tpd
@@ -1,17 +1,17 @@ -target "S20220927175816" with source configurePhase +target "S20221109014815" with source configurePhase // see https://download.eclipse.org/tools/orbit/downloads/ -location "https://download.eclipse.org/tools/orbit/downloads/drops/S20220927175816/repository" { +location "https://download.eclipse.org/tools/orbit/downloads/drops/S20221109014815/repository" { com.google.gson [2.9.1.v20220915-1632,2.9.1.v20220915-1632] com.google.gson.source [2.9.1.v20220915-1632,2.9.1.v20220915-1632] com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902] com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902] 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] - com.sun.jna [5.8.0.v20210503-0343,5.8.0.v20210503-0343] - com.sun.jna.source [5.8.0.v20210503-0343,5.8.0.v20210503-0343] - com.sun.jna.platform [5.8.0.v20210406-1004,5.8.0.v20210406-1004] - com.sun.jna.platform.source [5.8.0.v20210406-1004,5.8.0.v20210406-1004] + com.sun.jna [5.12.1.v20221103-2317,5.12.1.v20221103-2317] + com.sun.jna.source [5.12.1.v20221103-2317,5.12.1.v20221103-2317] + com.sun.jna.platform [5.12.1.v20221103-2317,5.12.1.v20221103-2317] + com.sun.jna.platform.source [5.12.1.v20221103-2317,5.12.1.v20221103-2317] javaewah [1.1.13.v20211029-0839,1.1.13.v20211029-0839] javaewah.source [1.1.13.v20211029-0839,1.1.13.v20211029-0839] net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410] @@ -38,14 +38,14 @@ org.apache.sshd.sftp.source [2.8.0.v20211227-1750,2.8.0.v20211227-1750] org.assertj [3.20.2.v20210706-1104,3.20.2.v20210706-1104] org.assertj.source [3.20.2.v20210706-1104,3.20.2.v20210706-1104] - org.bouncycastle.bcpg [1.71.0.v20220723-1943,1.71.0.v20220723-1943] - org.bouncycastle.bcpg.source [1.71.0.v20220723-1943,1.71.0.v20220723-1943] - org.bouncycastle.bcpkix [1.71.0.v20220723-1943,1.71.0.v20220723-1943] - org.bouncycastle.bcpkix.source [1.71.0.v20220723-1943,1.71.0.v20220723-1943] - org.bouncycastle.bcprov [1.71.0.v20220723-1943,1.71.0.v20220723-1943] - org.bouncycastle.bcprov.source [1.71.0.v20220723-1943,1.71.0.v20220723-1943] - org.bouncycastle.bcutil [1.71.0.v20220723-1943,1.71.0.v20220723-1943] - org.bouncycastle.bcutil.source [1.71.0.v20220723-1943,1.71.0.v20220723-1943] + org.bouncycastle.bcpg [1.72.0.v20221013-1810,1.72.0.v20221013-1810] + org.bouncycastle.bcpg.source [1.72.0.v20221013-1810,1.72.0.v20221013-1810] + org.bouncycastle.bcpkix [1.72.0.v20221013-1810,1.72.0.v20221013-1810] + org.bouncycastle.bcpkix.source [1.72.0.v20221013-1810,1.72.0.v20221013-1810] + org.bouncycastle.bcprov [1.72.0.v20221013-1810,1.72.0.v20221013-1810] + org.bouncycastle.bcprov.source [1.72.0.v20221013-1810,1.72.0.v20221013-1810] + org.bouncycastle.bcutil [1.72.0.v20221013-1810,1.72.0.v20221013-1810] + org.bouncycastle.bcutil.source [1.72.0.v20221013-1810,1.72.0.v20221013-1810] org.hamcrest [2.2.0.v20210711-0821,2.2.0.v20210711-0821] org.hamcrest.source [2.2.0.v20210711-0821,2.2.0.v20210711-0821] org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519] @@ -56,10 +56,10 @@ org.junit.source [4.13.2.v20211018-1956,4.13.2.v20211018-1956] org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218] org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218] - org.mockito [2.23.0.v20200310-1642,2.23.0.v20200310-1642] - org.mockito.source [2.23.0.v20200310-1642,2.23.0.v20200310-1642] - org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519] - org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519] + org.mockito.mockito-core [4.8.1.v20221103-2317,4.8.1.v20221103-2317] + org.mockito.mockito-core.source [4.8.1.v20221103-2317,4.8.1.v20221103-2317] + org.objenesis [3.3.0.v20221103-2317,3.3.0.v20221103-2317] + org.objenesis.source [3.3.0.v20221103-2317,3.3.0.v20221103-2317] org.slf4j.api [1.7.30.v20200204-2150,1.7.30.v20200204-2150] org.slf4j.api.source [1.7.30.v20200204-2150,1.7.30.v20200204-2150] org.slf4j.binding.simple [1.7.30.v20200204-2150,1.7.30.v20200204-2150]
diff --git a/org.eclipse.jgit.ssh.jsch/resources/org/eclipse/jgit/internal/transport/jsch/JSchText.properties b/org.eclipse.jgit.ssh.jsch/resources/org/eclipse/jgit/internal/transport/ssh/jsch/JSchText.properties similarity index 100% rename from org.eclipse.jgit.ssh.jsch/resources/org/eclipse/jgit/internal/transport/jsch/JSchText.properties rename to org.eclipse.jgit.ssh.jsch/resources/org/eclipse/jgit/internal/transport/ssh/jsch/JSchText.properties
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index 3ca9c84..c7f62a3 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -80,10 +80,10 @@ org.junit.rules;version="[4.13,5.0.0)", org.junit.runner;version="[4.13,5.0.0)", org.junit.runners;version="[4.13,5.0.0)", - org.mockito;version="[2.23.0,3.0.0)", - org.mockito.invocation;version="[2.23.0,3.0.0)", - org.mockito.junit;version="[2.23.0,3.0.0)", - org.mockito.stubbing;version="[2.23.0,3.0.0)", - org.objenesis;version="[2.6.0,3.0.0)", + org.mockito;version="[4.8.0,5.0.0)", + org.mockito.invocation;version="[4.8.0,5.0.0)", + org.mockito.junit;version="[4.8.0,5.0.0)", + org.mockito.stubbing;version="[4.8.0,5.0.0)", + org.objenesis;version="[3.3.0,4.0.0)", org.slf4j;version="[1.7.0,2.0.0)", org.tukaani.xz
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index 54cf540..6051edc 100644 --- a/org.eclipse.jgit.test/pom.xml +++ b/org.eclipse.jgit.test/pom.xml
@@ -73,7 +73,7 @@ <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>2.23.0</version> + <version>4.8.1</version> </dependency> <dependency>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/parser/FirstCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/parser/FirstCommandTest.java new file mode 100644 index 0000000..29819a4 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/parser/FirstCommandTest.java
@@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022, Google LLC. 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.internal.transport.parser; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Test; + +public class FirstCommandTest { + @Test + public void testClientSID() { + String oldStr = "0000000000000000000000000000000000000000"; + String newStr = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; + String refName = "refs/heads/master"; + String command = oldStr + " " + newStr + " " + refName; + String fl = command + "\0" + + "some capabilities session-id=the-clients-SID and more unknownCap=some-value"; + FirstCommand fc = FirstCommand.fromLine(fl); + + Map<String, String> options = fc.getCapabilities(); + + assertEquals("the-clients-SID", options.get("session-id")); + assertEquals(command, fc.getLine()); + assertTrue(options.containsKey("unknownCap")); + assertEquals(6, options.size()); + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/parser/FirstWantTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/parser/FirstWantTest.java index 1e8ce8e..230f6a4 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/parser/FirstWantTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/parser/FirstWantTest.java
@@ -27,7 +27,8 @@ public class FirstWantTest { @Test public void testFirstWantWithOptions() throws PackProtocolException { String line = "want b9d4d1eb2f93058814480eae9e1b67550f46ee38 " - + "no-progress include-tag ofs-delta agent=JGit/unknown"; + + "no-progress include-tag ofs-delta agent=JGit/unknown " + + "session-id=the.client.sid"; FirstWant r = FirstWant.fromLine(line); assertEquals("want b9d4d1eb2f93058814480eae9e1b67550f46ee38", @@ -37,6 +38,7 @@ public void testFirstWantWithOptions() throws PackProtocolException { Arrays.asList("no-progress", "include-tag", "ofs-delta")); assertEquals(expectedCapabilities, capabilities); assertEquals("JGit/unknown", r.getAgent()); + assertEquals("the.client.sid", r.getClientSID()); } @Test @@ -94,4 +96,12 @@ public void testFirstWantValidAgentName() throws PackProtocolException { assertEquals(r.getCapabilities().size(), 0); assertEquals("pack.age/Version", r.getAgent()); } + + @Test + public void testFirstWantValidSessionID() throws PackProtocolException { + FirstWant r = FirstWant + .fromLine(makeFirstWantLine("session-id=client.session.id")); + assertEquals(r.getCapabilities().size(), 0); + assertEquals("client.session.id", r.getClientSID()); + } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java index b2a4af3..61b7fb6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java
@@ -98,6 +98,25 @@ public void testRecvWantsWithAgent() "f900c8326a43303685c46b279b9f70411bff1a4b")); } + @Test + public void testRecvWantsWithSessionID() + throws PackProtocolException, IOException { + PacketLineIn pckIn = formatAsPacketLine(String.join(" ", "want", + "4624442d68ee402a94364191085b77137618633e", "thin-pack", + "agent=JGit.test/0.0.1", "session-id=client-session-id", "\n"), + "want f900c8326a43303685c46b279b9f70411bff1a4b\n", + PacketLineIn.end()); + ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); + FetchV0Request request = parser.recvWants(pckIn); + assertTrue(request.getClientCapabilities() + .contains(GitProtocolConstants.OPTION_THIN_PACK)); + assertEquals(1, request.getClientCapabilities().size()); + assertEquals("client-session-id", request.getClientSID()); + assertThat(request.getWantIds(), + hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e", + "f900c8326a43303685c46b279b9f70411bff1a4b")); + } + /* * First round of protocol v0 negotiation. Client send wants, no * capabilities.
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java index 167b5b7..bab4a36 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java
@@ -361,4 +361,28 @@ public void testLsRefsRefPrefixes() throws IOException { assertEquals(2, req.getRefPrefixes().size()); assertThat(req.getRefPrefixes(), hasItems("refs/for", "refs/heads")); } + + @Test + public void testFetchWithSessionID() throws IOException { + PacketLineIn pckIn = formatAsPacketLine("session-id=the.client.sid", + PacketLineIn.end()); + + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.start().allowFilter().done()); + FetchV2Request request = parser.parseFetchRequest(pckIn); + + assertEquals("the.client.sid", request.getClientSID()); + } + + @Test + public void testLsRefsWithSessionID() throws IOException { + PacketLineIn pckIn = formatAsPacketLine("session-id=the.client.sid", + PacketLineIn.delimiter(), PacketLineIn.end()); + + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.getDefault()); + LsRefsV2Request req = parser.parseLsRefsRequest(pckIn); + + assertEquals("the.client.sid", req.getClientSID()); + } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransferConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransferConfigTest.java index d9b85fb..8dad571 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransferConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransferConfigTest.java
@@ -11,6 +11,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import org.eclipse.jgit.lib.Config; import org.junit.Test; @@ -66,4 +68,19 @@ public void testParseProtocolInvalid() { TransferConfig tc = new TransferConfig(rc); assertNull(tc.protocolVersion); } + + @Test + public void testParseAdvertiseSIDDefault() { + Config rc = new Config(); + TransferConfig tc = new TransferConfig(rc); + assertFalse(tc.isAllowReceiveClientSID()); + } + + @Test + public void testParseAdvertiseSIDSet() { + Config rc = new Config(); + rc.setBoolean("transfer", null, "advertiseSID", true); + TransferConfig tc = new TransferConfig(rc); + assertTrue(tc.isAllowReceiveClientSID()); + } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java index 7131905..df48afe 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
@@ -2429,6 +2429,24 @@ public void testGetPeerAgentProtocolV0() throws Exception { } @Test + public void testGetSessionIDValueProtocolV0() throws Exception { + RevCommit one = remote.commit().message("1").create(); + remote.update("one", one); + + UploadPack up = new UploadPack(server); + ByteArrayInputStream send = linesAsInputStream( + "want " + one.getName() + " agent=JGit-test/1.2.3" + + " session-id=client-session-id\n", + PacketLineIn.end(), + "have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n"); + + ByteArrayOutputStream recv = new ByteArrayOutputStream(); + up.upload(send, recv, null); + + assertEquals(up.getClientSID(), "client-session-id"); + } + + @Test public void testGetPeerAgentProtocolV2() throws Exception { server.getConfig().setString(ConfigConstants.CONFIG_PROTOCOL_SECTION, null, ConfigConstants.CONFIG_KEY_VERSION, @@ -2452,6 +2470,30 @@ public void testGetPeerAgentProtocolV2() throws Exception { assertEquals(up.getPeerUserAgent(), "JGit-test/1.2.4"); } + @Test + public void testGetSessionIDValueProtocolV2() throws Exception { + server.getConfig().setString(ConfigConstants.CONFIG_PROTOCOL_SECTION, + null, ConfigConstants.CONFIG_KEY_VERSION, + TransferConfig.ProtocolVersion.V2.version()); + + RevCommit one = remote.commit().message("1").create(); + remote.update("one", one); + + UploadPack up = new UploadPack(server); + up.setExtraParameters(Sets.of("version=2")); + + ByteArrayInputStream send = linesAsInputStream("command=fetch\n", + "agent=JGit-test/1.2.4\n", "session-id=client-session-id\n", + PacketLineIn.delimiter(), "want " + one.getName() + "\n", + "have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n", + PacketLineIn.end()); + + ByteArrayOutputStream recv = new ByteArrayOutputStream(); + up.upload(send, recv, null); + + assertEquals(up.getClientSID(), "client-session-id"); + } + private static class RejectAllRefFilter implements RefFilter { @Override public Map<String, Ref> filter(Map<String, Ref> refs) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java index ad560c2..abc2854 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java
@@ -14,6 +14,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import java.io.IOException; @@ -22,11 +23,20 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import org.eclipse.jgit.junit.MockSystemReader; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.util.IO; -import org.junit.Test; +import org.eclipse.jgit.util.SystemReader; +import org.eclipse.jgit.util.sha1.SHA1.Sha1Implementation; +import org.junit.After; +import org.junit.Before; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; +@RunWith(Theories.class) public class SHA1Test { private static final String TEST1 = "abc"; @@ -34,7 +44,32 @@ public class SHA1Test { private static final String TEST2b = "jkijkljklmklmnlmnomnopnopq"; private static final String TEST2 = TEST2a + TEST2b; - @Test + @DataPoints + public static Sha1Implementation[] getDataPoints() { + return new Sha1Implementation[] { Sha1Implementation.JAVA, + Sha1Implementation.JDKNATIVE }; + } + + private Sha1Implementation sha1Implementation; + + public SHA1Test(Sha1Implementation impl) { + this.sha1Implementation = impl; + } + + @Before + public void setUp() throws Exception { + MockSystemReader mockSystemReader = new MockSystemReader(); + SystemReader.setInstance(mockSystemReader); + System.setProperty("org.eclipse.jgit.util.sha1.implementation", + sha1Implementation.name()); + } + + @After + public void tearDown() { + SystemReader.setInstance(null); + } + + @Theory public void test0() throws NoSuchAlgorithmException { ObjectId exp = ObjectId .fromString("da39a3ee5e6b4b0d3255bfef95601890afd80709"); @@ -56,7 +91,7 @@ public void test0() throws NoSuchAlgorithmException { assertEquals(exp, s2); } - @Test + @Theory public void test1() throws NoSuchAlgorithmException { ObjectId exp = ObjectId .fromString("a9993e364706816aba3e25717850c26c9cd0d89d"); @@ -78,7 +113,7 @@ public void test1() throws NoSuchAlgorithmException { assertEquals(exp, s2); } - @Test + @Theory public void test2() throws NoSuchAlgorithmException { ObjectId exp = ObjectId .fromString("84983e441c3bd26ebaae4aa1f95129e5e54670f1"); @@ -100,9 +135,13 @@ public void test2() throws NoSuchAlgorithmException { assertEquals(exp, s2); } - @Test + @Theory public void shatteredCollision() throws IOException, NoSuchAlgorithmException { + assumeFalse( + System.getProperty("org.eclipse.jgit.util.sha1.implementation") + .equalsIgnoreCase("jdkNative")); + byte[] pdf1 = read("shattered-1.pdf", 422435); byte[] pdf2 = read("shattered-2.pdf", 422435); MessageDigest md; @@ -149,8 +188,12 @@ public void shatteredCollision() } } - @Test + @Theory public void shatteredStoredInGitBlob() throws IOException { + assumeFalse( + System.getProperty("org.eclipse.jgit.util.sha1.implementation") + .equalsIgnoreCase("jdkNative")); + byte[] pdf1 = read("shattered-1.pdf", 422435); byte[] pdf2 = read("shattered-2.pdf", 422435); @@ -158,8 +201,10 @@ public void shatteredStoredInGitBlob() throws IOException { // the Git blob header permutes the data enough for this specific // attack example to not be detected as a collision. (A different file // pair that takes the Git header into account however, would.) - ObjectId id1 = blob(pdf1, SHA1.newInstance().setDetectCollision(true)); - ObjectId id2 = blob(pdf2, SHA1.newInstance().setDetectCollision(true)); + ObjectId id1 = blob(pdf1, + SHA1.newInstance().setDetectCollision(true)); + ObjectId id2 = blob(pdf2, + SHA1.newInstance().setDetectCollision(true)); assertEquals( ObjectId.fromString("ba9aaa145ccd24ef760cf31c74d8f7ca1a2e47b0"), @@ -169,8 +214,12 @@ public void shatteredStoredInGitBlob() throws IOException { id2); } - @Test + @Theory public void detectsShatteredByDefault() throws IOException { + assumeFalse( + System.getProperty("org.eclipse.jgit.util.sha1.implementation") + .equalsIgnoreCase("jdkNative")); + assumeTrue(System.getProperty("org.eclipse.jgit.util.sha1.detectCollision") == null); assumeTrue(System.getProperty("org.eclipse.jgit.util.sha1.safeHash") == null);
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters deleted file mode 100644 index 6992fa9..0000000 --- a/org.eclipse.jgit/.settings/.api_filters +++ /dev/null
@@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<component id="org.eclipse.jgit" version="2"> - <resource path="src/org/eclipse/jgit/transport/Transport.java" type="org.eclipse.jgit.transport.Transport"> - <filter id="336658481"> - <message_arguments> - <message_argument value="org.eclipse.jgit.transport.Transport"/> - <message_argument value="DEFAULT_PUSH_USE_BITMAPS"/> - </message_arguments> - </filter> - </resource> -</component>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java index 9c1d33d..8b0ea4f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
@@ -86,10 +86,16 @@ */ class PackedBatchRefUpdate extends BatchRefUpdate { private RefDirectory refdb; + private boolean shouldLockLooseRefs; PackedBatchRefUpdate(RefDirectory refdb) { - super(refdb); - this.refdb = refdb; + this(refdb, true); + } + + PackedBatchRefUpdate(RefDirectory refdb, boolean shouldLockLooseRefs) { + super(refdb); + this.refdb = refdb; + this.shouldLockLooseRefs = shouldLockLooseRefs; } /** {@inheritDoc} */ @@ -155,7 +161,7 @@ public void execute(RevWalk walk, ProgressMonitor monitor, refdb.inProcessPackedRefsLock.lock(); try { PackedRefList oldPackedList; - if (!refdb.isInClone()) { + if (!refdb.isInClone() && shouldLockLooseRefs) { locks = lockLooseRefs(pending); if (locks == null) { return;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java index 4aa2edf..7d3792e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
@@ -586,6 +586,21 @@ public PackedBatchRefUpdate newBatchUpdate() { return new PackedBatchRefUpdate(this); } + /** + * Create a new batch update to attempt on this database. + * + * @param shouldLockLooseRefs + * whether loose refs should be locked during the batch ref + * update. Note that this should only be set to {@code false} if + * the application using this ensures that no other ref updates + * run concurrently to avoid lost updates caused by a race. In + * such cases it can improve performance. + * @return a new batch update object + */ + public PackedBatchRefUpdate newBatchUpdate(boolean shouldLockLooseRefs) { + return new PackedBatchRefUpdate(this, shouldLockLooseRefs); + } + /** {@inheritDoc} */ @Override public boolean performsAtomicTransactions() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/parser/FirstCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/parser/FirstCommand.java index 3f90080..c75cf5d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/parser/FirstCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/parser/FirstCommand.java
@@ -9,12 +9,10 @@ */ package org.eclipse.jgit.internal.transport.parser; -import static java.util.Arrays.asList; -import static java.util.Collections.emptySet; -import static java.util.Collections.unmodifiableSet; -import static java.util.stream.Collectors.toSet; -import java.util.Set; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import org.eclipse.jgit.annotations.NonNull; @@ -34,7 +32,7 @@ */ public final class FirstCommand { private final String line; - private final Set<String> capabilities; + private final Map<String, String> capabilities; /** * Parse the first line of a receive-pack request. @@ -47,16 +45,26 @@ public final class FirstCommand { public static FirstCommand fromLine(String line) { int nul = line.indexOf('\0'); if (nul < 0) { - return new FirstCommand(line, emptySet()); + return new FirstCommand(line, + Collections.<String, String> emptyMap()); } - Set<String> opts = - asList(line.substring(nul + 1).split(" ")) //$NON-NLS-1$ - .stream() - .collect(toSet()); - return new FirstCommand(line.substring(0, nul), unmodifiableSet(opts)); + String[] splitCapablities = line.substring(nul + 1).split(" "); //$NON-NLS-1$ + Map<String, String> options = new HashMap<>(); + + for (String c : splitCapablities) { + int i = c.indexOf("="); //$NON-NLS-1$ + if (i != -1) { + options.put(c.substring(0, i), c.substring(i + 1)); + } else { + options.put(c, null); + } + } + + return new FirstCommand(line.substring(0, nul), + Collections.<String, String> unmodifiableMap(options)); } - private FirstCommand(String line, Set<String> capabilities) { + private FirstCommand(String line, Map<String, String> capabilities) { this.line = line; this.capabilities = capabilities; } @@ -67,9 +75,9 @@ public String getLine() { return line; } - /** @return capabilities parsed from the line, as an immutable set. */ + /** @return capabilities parsed from the line, as an immutable map. */ @NonNull - public Set<String> getCapabilities() { + public Map<String, String> getCapabilities() { return capabilities; } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/parser/FirstWant.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/parser/FirstWant.java index 8138f06..30d6296 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/parser/FirstWant.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/parser/FirstWant.java
@@ -10,6 +10,7 @@ package org.eclipse.jgit.internal.transport.parser; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SESSION_ID; import java.util.Collections; import java.util.HashSet; @@ -43,8 +44,13 @@ public class FirstWant { @Nullable private final String agent; + @Nullable + private final String clientSID; + private static final String AGENT_PREFIX = OPTION_AGENT + '='; + private static final String SESSION_ID_PREFIX = OPTION_SESSION_ID + '='; + /** * Parse the first want line in the protocol v0/v1 pack negotiation. * @@ -58,6 +64,7 @@ public static FirstWant fromLine(String line) throws PackProtocolException { String wantLine; Set<String> capabilities; String agent = null; + String clientSID = null; if (line.length() > 45) { String opt = line.substring(45); @@ -70,6 +77,9 @@ public static FirstWant fromLine(String line) throws PackProtocolException { for (String clientCapability : opt.split(" ")) { //$NON-NLS-1$ if (clientCapability.startsWith(AGENT_PREFIX)) { agent = clientCapability.substring(AGENT_PREFIX.length()); + } else if (clientCapability.startsWith(SESSION_ID_PREFIX)) { + clientSID = clientCapability + .substring(SESSION_ID_PREFIX.length()); } else { opts.add(clientCapability); } @@ -81,14 +91,15 @@ public static FirstWant fromLine(String line) throws PackProtocolException { capabilities = Collections.emptySet(); } - return new FirstWant(wantLine, capabilities, agent); + return new FirstWant(wantLine, capabilities, agent, clientSID); } private FirstWant(String line, Set<String> capabilities, - @Nullable String agent) { + @Nullable String agent, @Nullable String clientSID) { this.line = line; this.capabilities = capabilities; this.agent = agent; + this.clientSID = clientSID; } /** @return non-capabilities part of the line. */ @@ -98,7 +109,7 @@ public String getLine() { /** * @return capabilities parsed from the line as an immutable set (excluding - * agent). + * agent and session-id). */ public Set<String> getCapabilities() { return capabilities; @@ -109,4 +120,10 @@ public Set<String> getCapabilities() { public String getAgent() { return agent; } + + /** @return client session-id parsed from the line. */ + @Nullable + public String getClientSID() { + return clientSID; + } }
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 2342cad..47a572b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -538,6 +538,13 @@ public final class ConfigConstants { public static final String CONFIG_KEY_SUPPORTSATOMICFILECREATION = "supportsatomicfilecreation"; /** + * The "sha1Implementation" key in the "core" section + * + * @since 5.13.2 + */ + public static final String SHA1_IMPLEMENTATION = "sha1implementation"; + + /** * The "noprefix" key in the "diff" section * @since 3.0 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java index 8b9b569..e56513d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -3,7 +3,8 @@ * Copyright (C) 2010-2012, Matthias Sohn <matthias.sohn@sap.com> * Copyright (C) 2012, Research In Motion Limited * Copyright (C) 2017, Obeo (mathieu.cartaud@obeo.fr) - * Copyright (C) 2018, 2022 Thomas Wolf <twolf@apache.org> and others + * Copyright (C) 2018, 2022 Thomas Wolf <twolf@apache.org> + * Copyright (C) 2022, Google Inc. 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 @@ -20,16 +21,26 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_ALGORITHM; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; +import java.io.Closeable; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; + import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.attributes.Attribute; import org.eclipse.jgit.attributes.Attributes; import org.eclipse.jgit.diff.DiffAlgorithm; import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm; @@ -38,16 +49,24 @@ import org.eclipse.jgit.diff.Sequence; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheBuildIterator; +import org.eclipse.jgit.dircache.DirCacheBuilder; +import org.eclipse.jgit.dircache.DirCacheCheckout; import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata; +import org.eclipse.jgit.dircache.DirCacheCheckout.StreamSupplier; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.errors.BinaryBlobException; +import org.eclipse.jgit.errors.IndexWriteException; +import org.eclipse.jgit.errors.NoWorkTreeException; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.CoreConfig.EolStreamType; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.storage.pack.PackConfig; @@ -56,11 +75,15 @@ import org.eclipse.jgit.treewalk.CanonicalTreeParser; import org.eclipse.jgit.treewalk.NameConflictTreeWalk; import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.TreeWalk.OperationType; import org.eclipse.jgit.treewalk.WorkingTreeIterator; +import org.eclipse.jgit.treewalk.WorkingTreeOptions; import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.LfsFactory; +import org.eclipse.jgit.util.LfsFactory.LfsInputStream; import org.eclipse.jgit.util.TemporaryBuffer; +import org.eclipse.jgit.util.io.EolStreamTypeUtil; /** * A three-way merger performing a content-merge if necessary @@ -68,6 +91,594 @@ public class ResolveMerger extends ThreeWayMerger { /** + * Handles work tree updates on both the checkout and the index. + * <p> + * You should use a single instance for all of your file changes. In case of + * an error, make sure your instance is released, and initiate a new one if + * necessary. + * + * @since 6.3.1 + */ + protected static class WorkTreeUpdater implements Closeable { + + /** + * The result of writing the index changes. + */ + public static class Result { + + private final List<String> modifiedFiles = new LinkedList<>(); + + private final List<String> failedToDelete = new LinkedList<>(); + + private ObjectId treeId = null; + + /** + * @return Modified tree ID if any, or null otherwise. + */ + public ObjectId getTreeId() { + return treeId; + } + + /** + * @return Files that couldn't be deleted. + */ + public List<String> getFailedToDelete() { + return failedToDelete; + } + + /** + * @return Files modified during this operation. + */ + public List<String> getModifiedFiles() { + return modifiedFiles; + } + } + + Result result = new Result(); + + /** + * The repository this handler operates on. + */ + @Nullable + private final Repository repo; + + /** + * Set to true if this operation should work in-memory. The repo's + * dircache and workingtree are not touched by this method. Eventually + * needed files are created as temporary files and a new empty, + * in-memory dircache will be used instead the repo's one. Often used + * for bare repos where the repo doesn't even have a workingtree and + * dircache. + */ + private final boolean inCore; + + private final ObjectInserter inserter; + + private final ObjectReader reader; + + private DirCache dirCache; + + private boolean implicitDirCache = false; + + /** + * Builder to update the dir cache during this operation. + */ + private DirCacheBuilder builder; + + /** + * The {@link WorkingTreeOptions} are needed to determine line endings + * for affected files. + */ + private WorkingTreeOptions workingTreeOptions; + + /** + * The size limit (bytes) which controls a file to be stored in + * {@code Heap} or {@code LocalFile} during the operation. + */ + private int inCoreFileSizeLimit; + + /** + * If the operation has nothing to do for a file but check it out at the + * end of the operation, it can be added here. + */ + private final Map<String, DirCacheEntry> toBeCheckedOut = new HashMap<>(); + + /** + * Files in this list will be deleted from the local copy at the end of + * the operation. + */ + private final TreeMap<String, File> toBeDeleted = new TreeMap<>(); + + /** + * Keeps {@link CheckoutMetadata} for {@link #checkout()}. + */ + private Map<String, CheckoutMetadata> checkoutMetadataByPath; + + /** + * Keeps {@link CheckoutMetadata} for {@link #revertModifiedFiles()}. + */ + private Map<String, CheckoutMetadata> cleanupMetadataByPath; + + /** + * Whether the changes were successfully written. + */ + private boolean indexChangesWritten; + + /** + * @param repo + * the {@link Repository}. + * @param dirCache + * if set, use the provided dir cache. Otherwise, use the + * default repository one + */ + private WorkTreeUpdater(Repository repo, DirCache dirCache) { + this.repo = repo; + this.dirCache = dirCache; + + this.inCore = false; + this.inserter = repo.newObjectInserter(); + this.reader = inserter.newReader(); + Config config = repo.getConfig(); + this.workingTreeOptions = config.get(WorkingTreeOptions.KEY); + this.inCoreFileSizeLimit = getInCoreFileSizeLimit(config); + this.checkoutMetadataByPath = new HashMap<>(); + this.cleanupMetadataByPath = new HashMap<>(); + } + + /** + * Creates a new {@link WorkTreeUpdater} for the given repository. + * + * @param repo + * the {@link Repository}. + * @param dirCache + * if set, use the provided dir cache. Otherwise, use the + * default repository one + * @return the {@link WorkTreeUpdater}. + */ + public static WorkTreeUpdater createWorkTreeUpdater(Repository repo, + DirCache dirCache) { + return new WorkTreeUpdater(repo, dirCache); + } + + /** + * @param repo + * the {@link Repository}. + * @param dirCache + * if set, use the provided dir cache. Otherwise, creates a + * new one + * @param oi + * to use for writing the modified objects with. + */ + private WorkTreeUpdater(Repository repo, DirCache dirCache, + ObjectInserter oi) { + this.repo = repo; + this.dirCache = dirCache; + this.inserter = oi; + + this.inCore = true; + this.reader = oi.newReader(); + if (repo != null) { + this.inCoreFileSizeLimit = getInCoreFileSizeLimit( + repo.getConfig()); + } + } + + /** + * Creates a new {@link WorkTreeUpdater} that works in memory only. + * + * @param repo + * the {@link Repository}. + * @param dirCache + * if set, use the provided dir cache. Otherwise, creates a + * new one + * @param oi + * to use for writing the modified objects with. + * @return the {@link WorkTreeUpdater} + */ + public static WorkTreeUpdater createInCoreWorkTreeUpdater( + Repository repo, DirCache dirCache, ObjectInserter oi) { + return new WorkTreeUpdater(repo, dirCache, oi); + } + + private static int getInCoreFileSizeLimit(Config config) { + return config.getInt(ConfigConstants.CONFIG_MERGE_SECTION, + ConfigConstants.CONFIG_KEY_IN_CORE_LIMIT, 10 << 20); + } + + /** + * Gets the size limit for in-core files in this config. + * + * @return the size + */ + public int getInCoreFileSizeLimit() { + return inCoreFileSizeLimit; + } + + /** + * Gets dir cache for the repo. Locked if not inCore. + * + * @return the result dir cache + * @throws IOException + * is case the dir cache cannot be read + */ + public DirCache getLockedDirCache() throws IOException { + if (dirCache == null) { + implicitDirCache = true; + if (inCore) { + dirCache = DirCache.newInCore(); + } else { + dirCache = nonNullRepo().lockDirCache(); + } + } + if (builder == null) { + builder = dirCache.builder(); + } + return dirCache; + } + + /** + * Creates a {@link DirCacheBuildIterator} for the builder of this + * {@link WorkTreeUpdater}. + * + * @return the {@link DirCacheBuildIterator} + */ + public DirCacheBuildIterator createDirCacheBuildIterator() { + return new DirCacheBuildIterator(builder); + } + + /** + * Writes the changes to the working tree (but not to the index). + * + * @param shouldCheckoutTheirs + * before committing the changes + * @throws IOException + * if any of the writes fail + */ + public void writeWorkTreeChanges(boolean shouldCheckoutTheirs) + throws IOException { + handleDeletedFiles(); + + if (inCore) { + builder.finish(); + return; + } + if (shouldCheckoutTheirs) { + // No problem found. The only thing left to be done is to + // check out all files from "theirs" which have been selected to + // go into the new index. + checkout(); + } + + // All content operations are successfully done. If we can now write + // the + // new index we are on quite safe ground. Even if the checkout of + // files coming from "theirs" fails the user can work around such + // failures by checking out the index again. + if (!builder.commit()) { + revertModifiedFiles(); + throw new IndexWriteException(); + } + } + + /** + * Writes the changes to the index. + * + * @return the {@link Result} of the operation. + * @throws IOException + * if any of the writes fail + */ + public Result writeIndexChanges() throws IOException { + result.treeId = getLockedDirCache().writeTree(inserter); + indexChangesWritten = true; + return result; + } + + /** + * Adds a {@link DirCacheEntry} for direct checkout and remembers its + * {@link CheckoutMetadata}. + * + * @param path + * of the entry + * @param entry + * to add + * @param cleanupStreamType + * to use for the cleanup metadata + * @param cleanupSmudgeCommand + * to use for the cleanup metadata + * @param checkoutStreamType + * to use for the checkout metadata + * @param checkoutSmudgeCommand + * to use for the checkout metadata + */ + public void addToCheckout(String path, DirCacheEntry entry, + EolStreamType cleanupStreamType, String cleanupSmudgeCommand, + EolStreamType checkoutStreamType, + String checkoutSmudgeCommand) { + if (entry != null) { + // In some cases, we just want to add the metadata. + toBeCheckedOut.put(path, entry); + } + addCheckoutMetadata(cleanupMetadataByPath, path, cleanupStreamType, + cleanupSmudgeCommand); + addCheckoutMetadata(checkoutMetadataByPath, path, + checkoutStreamType, checkoutSmudgeCommand); + } + + /** + * Gets a map which maps the paths of files which have to be checked out + * because the operation created new fully-merged content for this file + * into the index. + * <p> + * This means: the operation wrote a new stage 0 entry for this path. + * </p> + * + * @return the map + */ + public Map<String, DirCacheEntry> getToBeCheckedOut() { + return toBeCheckedOut; + } + + /** + * Remembers the given file to be deleted. + * <p> + * Note the actual deletion is only done in + * {@link #writeWorkTreeChanges}. + * + * @param path + * of the file to be deleted + * @param file + * to be deleted + * @param streamType + * to use for cleanup metadata + * @param smudgeCommand + * to use for cleanup metadata + */ + public void deleteFile(String path, File file, EolStreamType streamType, + String smudgeCommand) { + toBeDeleted.put(path, file); + if (file != null && file.isFile()) { + addCheckoutMetadata(cleanupMetadataByPath, path, streamType, + smudgeCommand); + } + } + + /** + * Remembers the {@link CheckoutMetadata} for the given path; it may be + * needed in {@link #checkout()} or in {@link #revertModifiedFiles()}. + * + * @param map + * to add the metadata to + * @param path + * of the current node + * @param streamType + * to use for the metadata + * @param smudgeCommand + * to use for the metadata + */ + private void addCheckoutMetadata(Map<String, CheckoutMetadata> map, + String path, EolStreamType streamType, String smudgeCommand) { + if (inCore || map == null) { + return; + } + map.put(path, new CheckoutMetadata(streamType, smudgeCommand)); + } + + /** + * Detects if CRLF conversion has been configured. + * <p> + * </p> + * See {@link EolStreamTypeUtil#detectStreamType} for more info. + * + * @param attributes + * of the file for which the type is to be detected + * @return the detected type + */ + public EolStreamType detectCheckoutStreamType(Attributes attributes) { + if (inCore) { + return null; + } + return EolStreamTypeUtil.detectStreamType(OperationType.CHECKOUT_OP, + workingTreeOptions, attributes); + } + + private void handleDeletedFiles() { + // Iterate in reverse so that "folder/file" is deleted before + // "folder". Otherwise, this could result in a failing path because + // of a non-empty directory, for which delete() would fail. + for (String path : toBeDeleted.descendingKeySet()) { + File file = inCore ? null : toBeDeleted.get(path); + if (file != null && !file.delete()) { + if (!file.isDirectory()) { + result.failedToDelete.add(path); + } + } + } + } + + /** + * Marks the given path as modified in the operation. + * + * @param path + * to mark as modified + */ + public void markAsModified(String path) { + result.modifiedFiles.add(path); + } + + /** + * Gets the list of files which were modified in this operation. + * + * @return the list + */ + public List<String> getModifiedFiles() { + return result.modifiedFiles; + } + + private void checkout() throws NoWorkTreeException, IOException { + for (Map.Entry<String, DirCacheEntry> entry : toBeCheckedOut + .entrySet()) { + DirCacheEntry dirCacheEntry = entry.getValue(); + if (dirCacheEntry.getFileMode() == FileMode.GITLINK) { + new File(nonNullRepo().getWorkTree(), entry.getKey()) + .mkdirs(); + } else { + DirCacheCheckout.checkoutEntry(repo, dirCacheEntry, reader, + false, checkoutMetadataByPath.get(entry.getKey()), + workingTreeOptions); + result.modifiedFiles.add(entry.getKey()); + } + } + } + + /** + * Reverts any uncommitted changes in the worktree. We know that for all + * modified files the old content was in the old index and the index + * contained only stage 0. In case of inCore operation just clear the + * history of modified files. + * + * @throws IOException + * in case the cleaning up failed + */ + public void revertModifiedFiles() throws IOException { + if (inCore) { + result.modifiedFiles.clear(); + return; + } + if (indexChangesWritten) { + return; + } + for (String path : result.modifiedFiles) { + DirCacheEntry entry = dirCache.getEntry(path); + if (entry != null) { + DirCacheCheckout.checkoutEntry(repo, entry, reader, false, + cleanupMetadataByPath.get(path), + workingTreeOptions); + } + } + } + + @Override + public void close() throws IOException { + if (implicitDirCache) { + dirCache.unlock(); + } + } + + /** + * Updates the file in the checkout with the given content. + * + * @param inputStream + * the content to be updated + * @param streamType + * for parsing the content + * @param smudgeCommand + * for formatting the content + * @param path + * of the file to be updated + * @param file + * to be updated + * @throws IOException + * if the file cannot be updated + */ + public void updateFileWithContent(StreamSupplier inputStream, + EolStreamType streamType, String smudgeCommand, String path, + File file) throws IOException { + if (inCore) { + return; + } + CheckoutMetadata metadata = new CheckoutMetadata(streamType, + smudgeCommand); + + try (OutputStream outputStream = new FileOutputStream(file)) { + DirCacheCheckout.getContent(repo, path, metadata, inputStream, + workingTreeOptions, outputStream); + } + } + + /** + * Creates a path with the given content, and adds it to the specified + * stage to the index builder. + * + * @param input + * the content to be updated + * @param path + * of the file to be updated + * @param fileMode + * of the modified file + * @param entryStage + * of the new entry + * @param lastModified + * instant of the modified file + * @param len + * of the content + * @param lfsAttribute + * for checking for LFS enablement + * @return the entry which was added to the index + * @throws IOException + * if inserting the content fails + */ + public DirCacheEntry insertToIndex(InputStream input, byte[] path, + FileMode fileMode, int entryStage, Instant lastModified, + int len, Attribute lfsAttribute) throws IOException { + return addExistingToIndex(insertResult(input, lfsAttribute, len), + path, fileMode, entryStage, lastModified, len); + } + + /** + * Adds a path with the specified stage to the index builder. + * + * @param objectId + * of the existing object to add + * @param path + * of the modified file + * @param fileMode + * of the modified file + * @param entryStage + * of the new entry + * @param lastModified + * instant of the modified file + * @param len + * of the modified file content + * @return the entry which was added to the index + */ + public DirCacheEntry addExistingToIndex(ObjectId objectId, byte[] path, + FileMode fileMode, int entryStage, Instant lastModified, + int len) { + DirCacheEntry dce = new DirCacheEntry(path, entryStage); + dce.setFileMode(fileMode); + if (lastModified != null) { + dce.setLastModified(lastModified); + } + dce.setLength(inCore ? 0 : len); + dce.setObjectId(objectId); + builder.add(dce); + return dce; + } + + private ObjectId insertResult(InputStream input, Attribute lfsAttribute, + long length) throws IOException { + try (LfsInputStream is = LfsFactory.getInstance() + .applyCleanFilter(repo, input, length, lfsAttribute)) { + return inserter.insert(OBJ_BLOB, is.getLength(), is); + } + } + + /** + * Gets the non-null repository instance of this + * {@link WorkTreeUpdater}. + * + * @return non-null repository instance + * @throws NullPointerException + * if the handler was constructed without a repository. + */ + @NonNull + private Repository nonNullRepo() throws NullPointerException { + return Objects.requireNonNull(repo, + () -> JGitText.get().repositoryIsRequired); + } + } + + /** * If the merge fails (means: not stopped because of unresolved conflicts) * this enum is used to explain why it failed */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/WorkTreeUpdater.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/WorkTreeUpdater.java deleted file mode 100644 index 1db9bc6..0000000 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/WorkTreeUpdater.java +++ /dev/null
@@ -1,635 +0,0 @@ -/* - * Copyright (C) 2022, Google Inc. 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.merge; - -import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; - -import java.io.Closeable; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.time.Instant; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.TreeMap; - -import org.eclipse.jgit.annotations.NonNull; -import org.eclipse.jgit.annotations.Nullable; -import org.eclipse.jgit.attributes.Attribute; -import org.eclipse.jgit.attributes.Attributes; -import org.eclipse.jgit.dircache.DirCache; -import org.eclipse.jgit.dircache.DirCacheBuildIterator; -import org.eclipse.jgit.dircache.DirCacheBuilder; -import org.eclipse.jgit.dircache.DirCacheCheckout; -import org.eclipse.jgit.dircache.DirCacheCheckout.StreamSupplier; -import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata; -import org.eclipse.jgit.dircache.DirCacheEntry; -import org.eclipse.jgit.errors.IndexWriteException; -import org.eclipse.jgit.errors.NoWorkTreeException; -import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.lib.Config; -import org.eclipse.jgit.lib.ConfigConstants; -import org.eclipse.jgit.lib.CoreConfig.EolStreamType; -import org.eclipse.jgit.lib.FileMode; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.ObjectInserter; -import org.eclipse.jgit.lib.ObjectReader; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.treewalk.TreeWalk.OperationType; -import org.eclipse.jgit.treewalk.WorkingTreeOptions; -import org.eclipse.jgit.util.LfsFactory; -import org.eclipse.jgit.util.LfsFactory.LfsInputStream; -import org.eclipse.jgit.util.io.EolStreamTypeUtil; - -/** - * Handles work tree updates on both the checkout and the index. - * <p> - * You should use a single instance for all of your file changes. In case of an - * error, make sure your instance is released, and initiate a new one if - * necessary. - */ -class WorkTreeUpdater implements Closeable { - - /** - * The result of writing the index changes. - */ - public static class Result { - - private final List<String> modifiedFiles = new LinkedList<>(); - - - private final List<String> failedToDelete = new LinkedList<>(); - - private ObjectId treeId = null; - - /** - * @return Modified tree ID if any, or null otherwise. - */ - public ObjectId getTreeId() { - return treeId; - } - - /** - * @return Files that couldn't be deleted. - */ - public List<String> getFailedToDelete() { - return failedToDelete; - } - - /** - * @return Files modified during this operation. - */ - public List<String> getModifiedFiles() { - return modifiedFiles; - } - } - - Result result = new Result(); - - /** - * The repository this handler operates on. - */ - @Nullable - private final Repository repo; - - /** - * Set to true if this operation should work in-memory. The repo's dircache - * and workingtree are not touched by this method. Eventually needed files - * are created as temporary files and a new empty, in-memory dircache will - * be used instead the repo's one. Often used for bare repos where the repo - * doesn't even have a workingtree and dircache. - */ - private final boolean inCore; - - private final ObjectInserter inserter; - - private final ObjectReader reader; - - private DirCache dirCache; - - private boolean implicitDirCache = false; - - /** - * Builder to update the dir cache during this operation. - */ - private DirCacheBuilder builder; - - /** - * The {@link WorkingTreeOptions} are needed to determine line endings for - * affected files. - */ - private WorkingTreeOptions workingTreeOptions; - - /** - * The size limit (bytes) which controls a file to be stored in {@code Heap} - * or {@code LocalFile} during the operation. - */ - private int inCoreFileSizeLimit; - - /** - * If the operation has nothing to do for a file but check it out at the end - * of the operation, it can be added here. - */ - private final Map<String, DirCacheEntry> toBeCheckedOut = new HashMap<>(); - - /** - * Files in this list will be deleted from the local copy at the end of the - * operation. - */ - private final TreeMap<String, File> toBeDeleted = new TreeMap<>(); - - /** - * Keeps {@link CheckoutMetadata} for {@link #checkout()}. - */ - private Map<String, CheckoutMetadata> checkoutMetadataByPath; - - /** - * Keeps {@link CheckoutMetadata} for {@link #revertModifiedFiles()}. - */ - private Map<String, CheckoutMetadata> cleanupMetadataByPath; - - /** - * Whether the changes were successfully written. - */ - private boolean indexChangesWritten; - - /** - * @param repo - * the {@link Repository}. - * @param dirCache - * if set, use the provided dir cache. Otherwise, use the default - * repository one - */ - private WorkTreeUpdater(Repository repo, DirCache dirCache) { - this.repo = repo; - this.dirCache = dirCache; - - this.inCore = false; - this.inserter = repo.newObjectInserter(); - this.reader = inserter.newReader(); - Config config = repo.getConfig(); - this.workingTreeOptions = config.get(WorkingTreeOptions.KEY); - this.inCoreFileSizeLimit = getInCoreFileSizeLimit(config); - this.checkoutMetadataByPath = new HashMap<>(); - this.cleanupMetadataByPath = new HashMap<>(); - } - - /** - * Creates a new {@link WorkTreeUpdater} for the given repository. - * - * @param repo - * the {@link Repository}. - * @param dirCache - * if set, use the provided dir cache. Otherwise, use the default - * repository one - * @return the {@link WorkTreeUpdater}. - */ - public static WorkTreeUpdater createWorkTreeUpdater(Repository repo, - DirCache dirCache) { - return new WorkTreeUpdater(repo, dirCache); - } - - /** - * @param repo - * the {@link Repository}. - * @param dirCache - * if set, use the provided dir cache. Otherwise, creates a new - * one - * @param oi - * to use for writing the modified objects with. - */ - private WorkTreeUpdater(Repository repo, DirCache dirCache, - ObjectInserter oi) { - this.repo = repo; - this.dirCache = dirCache; - this.inserter = oi; - - this.inCore = true; - this.reader = oi.newReader(); - if (repo != null) { - this.inCoreFileSizeLimit = getInCoreFileSizeLimit(repo.getConfig()); - } - } - - /** - * Creates a new {@link WorkTreeUpdater} that works in memory only. - * - * @param repo - * the {@link Repository}. - * @param dirCache - * if set, use the provided dir cache. Otherwise, creates a new - * one - * @param oi - * to use for writing the modified objects with. - * @return the {@link WorkTreeUpdater} - */ - public static WorkTreeUpdater createInCoreWorkTreeUpdater(Repository repo, - DirCache dirCache, ObjectInserter oi) { - return new WorkTreeUpdater(repo, dirCache, oi); - } - - private static int getInCoreFileSizeLimit(Config config) { - return config.getInt(ConfigConstants.CONFIG_MERGE_SECTION, - ConfigConstants.CONFIG_KEY_IN_CORE_LIMIT, 10 << 20); - } - - /** - * Gets the size limit for in-core files in this config. - * - * @return the size - */ - public int getInCoreFileSizeLimit() { - return inCoreFileSizeLimit; - } - - /** - * Gets dir cache for the repo. Locked if not inCore. - * - * @return the result dir cache - * @throws IOException - * is case the dir cache cannot be read - */ - public DirCache getLockedDirCache() throws IOException { - if (dirCache == null) { - implicitDirCache = true; - if (inCore) { - dirCache = DirCache.newInCore(); - } else { - dirCache = nonNullRepo().lockDirCache(); - } - } - if (builder == null) { - builder = dirCache.builder(); - } - return dirCache; - } - - /** - * Creates a {@link DirCacheBuildIterator} for the builder of this - * {@link WorkTreeUpdater}. - * - * @return the {@link DirCacheBuildIterator} - */ - public DirCacheBuildIterator createDirCacheBuildIterator() { - return new DirCacheBuildIterator(builder); - } - - /** - * Writes the changes to the working tree (but not to the index). - * - * @param shouldCheckoutTheirs - * before committing the changes - * @throws IOException - * if any of the writes fail - */ - public void writeWorkTreeChanges(boolean shouldCheckoutTheirs) - throws IOException { - handleDeletedFiles(); - - if (inCore) { - builder.finish(); - return; - } - if (shouldCheckoutTheirs) { - // No problem found. The only thing left to be done is to - // check out all files from "theirs" which have been selected to - // go into the new index. - checkout(); - } - - // All content operations are successfully done. If we can now write the - // new index we are on quite safe ground. Even if the checkout of - // files coming from "theirs" fails the user can work around such - // failures by checking out the index again. - if (!builder.commit()) { - revertModifiedFiles(); - throw new IndexWriteException(); - } - } - - /** - * Writes the changes to the index. - * - * @return the {@link Result} of the operation. - * @throws IOException - * if any of the writes fail - */ - public Result writeIndexChanges() throws IOException { - result.treeId = getLockedDirCache().writeTree(inserter); - indexChangesWritten = true; - return result; - } - - /** - * Adds a {@link DirCacheEntry} for direct checkout and remembers its - * {@link CheckoutMetadata}. - * - * @param path - * of the entry - * @param entry - * to add - * @param cleanupStreamType - * to use for the cleanup metadata - * @param cleanupSmudgeCommand - * to use for the cleanup metadata - * @param checkoutStreamType - * to use for the checkout metadata - * @param checkoutSmudgeCommand - * to use for the checkout metadata - */ - public void addToCheckout(String path, DirCacheEntry entry, - EolStreamType cleanupStreamType, String cleanupSmudgeCommand, - EolStreamType checkoutStreamType, String checkoutSmudgeCommand) { - if (entry != null) { - // In some cases, we just want to add the metadata. - toBeCheckedOut.put(path, entry); - } - addCheckoutMetadata(cleanupMetadataByPath, path, cleanupStreamType, - cleanupSmudgeCommand); - addCheckoutMetadata(checkoutMetadataByPath, path, checkoutStreamType, - checkoutSmudgeCommand); - } - - /** - * Gets a map which maps the paths of files which have to be checked out - * because the operation created new fully-merged content for this file into - * the index. - * <p> - * This means: the operation wrote a new stage 0 entry for this path. - * </p> - * - * @return the map - */ - public Map<String, DirCacheEntry> getToBeCheckedOut() { - return toBeCheckedOut; - } - - /** - * Remembers the given file to be deleted. - * <p> - * Note the actual deletion is only done in {@link #writeWorkTreeChanges}. - * - * @param path - * of the file to be deleted - * @param file - * to be deleted - * @param streamType - * to use for cleanup metadata - * @param smudgeCommand - * to use for cleanup metadata - */ - public void deleteFile(String path, File file, EolStreamType streamType, - String smudgeCommand) { - toBeDeleted.put(path, file); - if (file != null && file.isFile()) { - addCheckoutMetadata(cleanupMetadataByPath, path, streamType, - smudgeCommand); - } - } - - /** - * Remembers the {@link CheckoutMetadata} for the given path; it may be - * needed in {@link #checkout()} or in {@link #revertModifiedFiles()}. - * - * @param map - * to add the metadata to - * @param path - * of the current node - * @param streamType - * to use for the metadata - * @param smudgeCommand - * to use for the metadata - */ - private void addCheckoutMetadata(Map<String, CheckoutMetadata> map, - String path, EolStreamType streamType, String smudgeCommand) { - if (inCore || map == null) { - return; - } - map.put(path, new CheckoutMetadata(streamType, smudgeCommand)); - } - - /** - * Detects if CRLF conversion has been configured. - * <p> - * </p> - * See {@link EolStreamTypeUtil#detectStreamType} for more info. - * - * @param attributes - * of the file for which the type is to be detected - * @return the detected type - */ - public EolStreamType detectCheckoutStreamType(Attributes attributes) { - if (inCore) { - return null; - } - return EolStreamTypeUtil.detectStreamType(OperationType.CHECKOUT_OP, - workingTreeOptions, attributes); - } - - private void handleDeletedFiles() { - // Iterate in reverse so that "folder/file" is deleted before - // "folder". Otherwise, this could result in a failing path because - // of a non-empty directory, for which delete() would fail. - for (String path : toBeDeleted.descendingKeySet()) { - File file = inCore ? null : toBeDeleted.get(path); - if (file != null && !file.delete()) { - if (!file.isDirectory()) { - result.failedToDelete.add(path); - } - } - } - } - - /** - * Marks the given path as modified in the operation. - * - * @param path - * to mark as modified - */ - public void markAsModified(String path) { - result.modifiedFiles.add(path); - } - - /** - * Gets the list of files which were modified in this operation. - * - * @return the list - */ - public List<String> getModifiedFiles() { - return result.modifiedFiles; - } - - private void checkout() throws NoWorkTreeException, IOException { - for (Map.Entry<String, DirCacheEntry> entry : toBeCheckedOut - .entrySet()) { - DirCacheEntry dirCacheEntry = entry.getValue(); - if (dirCacheEntry.getFileMode() == FileMode.GITLINK) { - new File(nonNullRepo().getWorkTree(), entry.getKey()) - .mkdirs(); - } else { - DirCacheCheckout.checkoutEntry(repo, dirCacheEntry, reader, - false, checkoutMetadataByPath.get(entry.getKey()), - workingTreeOptions); - result.modifiedFiles.add(entry.getKey()); - } - } - } - - /** - * Reverts any uncommitted changes in the worktree. We know that for all - * modified files the old content was in the old index and the index - * contained only stage 0. In case of inCore operation just clear the - * history of modified files. - * - * @throws IOException - * in case the cleaning up failed - */ - public void revertModifiedFiles() throws IOException { - if (inCore) { - result.modifiedFiles.clear(); - return; - } - if (indexChangesWritten) { - return; - } - for (String path : result.modifiedFiles) { - DirCacheEntry entry = dirCache.getEntry(path); - if (entry != null) { - DirCacheCheckout.checkoutEntry(repo, entry, reader, false, - cleanupMetadataByPath.get(path), workingTreeOptions); - } - } - } - - @Override - public void close() throws IOException { - if (implicitDirCache) { - dirCache.unlock(); - } - } - - /** - * Updates the file in the checkout with the given content. - * - * @param inputStream - * the content to be updated - * @param streamType - * for parsing the content - * @param smudgeCommand - * for formatting the content - * @param path - * of the file to be updated - * @param file - * to be updated - * @throws IOException - * if the file cannot be updated - */ - public void updateFileWithContent(StreamSupplier inputStream, - EolStreamType streamType, String smudgeCommand, String path, - File file) throws IOException { - if (inCore) { - return; - } - CheckoutMetadata metadata = new CheckoutMetadata(streamType, - smudgeCommand); - - try (OutputStream outputStream = new FileOutputStream(file)) { - DirCacheCheckout.getContent(repo, path, metadata, - inputStream, workingTreeOptions, outputStream); - } - } - - /** - * Creates a path with the given content, and adds it to the specified stage - * to the index builder. - * - * @param input - * the content to be updated - * @param path - * of the file to be updated - * @param fileMode - * of the modified file - * @param entryStage - * of the new entry - * @param lastModified - * instant of the modified file - * @param len - * of the content - * @param lfsAttribute - * for checking for LFS enablement - * @return the entry which was added to the index - * @throws IOException - * if inserting the content fails - */ - public DirCacheEntry insertToIndex(InputStream input, - byte[] path, FileMode fileMode, int entryStage, - Instant lastModified, int len, Attribute lfsAttribute) - throws IOException { - return addExistingToIndex(insertResult(input, lfsAttribute, len), path, - fileMode, entryStage, lastModified, len); - } - - /** - * Adds a path with the specified stage to the index builder. - * - * @param objectId - * of the existing object to add - * @param path - * of the modified file - * @param fileMode - * of the modified file - * @param entryStage - * of the new entry - * @param lastModified - * instant of the modified file - * @param len - * of the modified file content - * @return the entry which was added to the index - */ - public DirCacheEntry addExistingToIndex(ObjectId objectId, byte[] path, - FileMode fileMode, int entryStage, Instant lastModified, int len) { - DirCacheEntry dce = new DirCacheEntry(path, entryStage); - dce.setFileMode(fileMode); - if (lastModified != null) { - dce.setLastModified(lastModified); - } - dce.setLength(inCore ? 0 : len); - dce.setObjectId(objectId); - builder.add(dce); - return dce; - } - - private ObjectId insertResult(InputStream input, - Attribute lfsAttribute, long length) throws IOException { - try (LfsInputStream is = LfsFactory.getInstance().applyCleanFilter(repo, - input, length, - lfsAttribute)) { - return inserter.insert(OBJ_BLOB, is.getLength(), is); - } - } - - /** - * Gets the non-null repository instance of this {@link WorkTreeUpdater}. - * - * @return non-null repository instance - * @throws NullPointerException - * if the handler was constructed without a repository. - */ - @NonNull - private Repository nonNullRepo() throws NullPointerException { - return Objects.requireNonNull(repo, - () -> JGitText.get().repositoryIsRequired); - } -}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java index 81a70af..4fec5da 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
@@ -115,7 +115,7 @@ private static String toCleanString(List<String> list) { for (String v : list) { if (s.length() > 0) s.append(','); - s.append(v.replaceAll("\n", "").trim()); //$NON-NLS-1$ //$NON-NLS-2$ + s.append(v.replace("\n", "").trim()); //$NON-NLS-1$ //$NON-NLS-2$ } return s.toString(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchRequest.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchRequest.java index 0663c51..009a70b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchRequest.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchRequest.java
@@ -40,6 +40,9 @@ abstract class FetchRequest { @Nullable final String agent; + @Nullable + final String clientSID; + /** * Initialize the common fields of a fetch request. * @@ -61,12 +64,15 @@ abstract class FetchRequest { * specific time, instead of depth * @param agent * agent as reported by the client in the request body + * @param clientSID + * agent as reported by the client in the request body */ FetchRequest(@NonNull Set<ObjectId> wantIds, int depth, @NonNull Set<ObjectId> clientShallowCommits, @NonNull FilterSpec filterSpec, @NonNull Set<String> clientCapabilities, int deepenSince, - @NonNull List<String> deepenNots, @Nullable String agent) { + @NonNull List<String> deepenNots, @Nullable String agent, + @Nullable String clientSID) { this.wantIds = requireNonNull(wantIds); this.depth = depth; this.clientShallowCommits = requireNonNull(clientShallowCommits); @@ -75,6 +81,7 @@ abstract class FetchRequest { this.deepenSince = deepenSince; this.deepenNots = requireNonNull(deepenNots); this.agent = agent; + this.clientSID = clientSID; } /** @@ -160,4 +167,13 @@ List<String> getDeepenNots() { String getAgent() { return agent; } + + /** + * @return string identifying the client session ID (as sent in the request body by the + * client) + */ + @Nullable + String getClientSID() { + return clientSID; + } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV0Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV0Request.java index 4decb79..ca3639d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV0Request.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV0Request.java
@@ -30,9 +30,11 @@ final class FetchV0Request extends FetchRequest { @NonNull Set<ObjectId> clientShallowCommits, @NonNull FilterSpec filterSpec, @NonNull Set<String> clientCapabilities, int deepenSince, - @NonNull List<String> deepenNotRefs, @Nullable String agent) { + @NonNull List<String> deepenNotRefs, @Nullable String agent, + @Nullable String clientSID) { super(wantIds, depth, clientShallowCommits, filterSpec, - clientCapabilities, deepenSince, deepenNotRefs, agent); + clientCapabilities, deepenSince, deepenNotRefs, agent, + clientSID); } static final class Builder { @@ -53,6 +55,8 @@ static final class Builder { String agent; + String clientSID; + /** * @param objectId * object id received in a "want" line @@ -149,6 +153,16 @@ Builder setAgent(String clientAgent) { } /** + * @param clientSID + * session-id line sent by the client in the request body + * @return this builder + */ + Builder setClientSID(String clientSID) { + this.clientSID = clientSID; + return this; + } + + /** * @param filter * the filter set in a filter line * @return this builder @@ -160,7 +174,8 @@ Builder setFilterSpec(@NonNull FilterSpec filter) { FetchV0Request build() { return new FetchV0Request(wantIds, depth, clientShallowCommits, - filterSpec, clientCaps, deepenSince, deepenNots, agent); + filterSpec, clientCaps, deepenSince, deepenNots, agent, + clientSID); } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java index 401744f..3d4f381 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java
@@ -55,10 +55,11 @@ public final class FetchV2Request extends FetchRequest { boolean doneReceived, boolean waitForDone, @NonNull Set<String> clientCapabilities, @Nullable String agent, @NonNull List<String> serverOptions, - boolean sidebandAll, @NonNull List<String> packfileUriProtocols) { + boolean sidebandAll, @NonNull List<String> packfileUriProtocols, + @Nullable String clientSID) { super(wantIds, depth, clientShallowCommits, filterSpec, clientCapabilities, deepenSince, - deepenNots, agent); + deepenNots, agent, clientSID); this.peerHas = requireNonNull(peerHas); this.wantedRefs = requireNonNull(wantedRefs); this.doneReceived = doneReceived; @@ -157,6 +158,9 @@ static final class Builder { @Nullable String agent; + @Nullable + String clientSID; + final List<String> serverOptions = new ArrayList<>(); boolean sidebandAll; @@ -317,6 +321,17 @@ Builder setAgent(@Nullable String agentValue) { } /** + * @param clientSIDValue + * the client-supplied session capability, without the + * leading "session-id=" + * @return this builder + */ + Builder setClientSID(@Nullable String clientSIDValue) { + clientSID = clientSIDValue; + return this; + } + + /** * Records an application-specific option supplied in a server-option * line, for later retrieval with * {@link FetchV2Request#getServerOptions}. @@ -354,7 +369,8 @@ FetchV2Request build() { depth, filterSpec, doneReceived, waitForDone, clientCapabilities, agent, Collections.unmodifiableList(serverOptions), sidebandAll, - Collections.unmodifiableList(packfileUriProtocols)); + Collections.unmodifiableList(packfileUriProtocols), + clientSID); } } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java index be14e92..7e5179d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
@@ -248,6 +248,13 @@ public final class GitProtocolConstants { public static final String OPTION_SERVER_OPTION = "server-option"; //$NON-NLS-1$ /** + * Option for passing client session ID to the server. + * + * @since 6.4 + */ + public static final String OPTION_SESSION_ID = "session-id"; //$NON-NLS-1$ + + /** * The server supports listing refs using protocol v2. * * @since 5.0
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java index f68d9c8..856047e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java
@@ -36,17 +36,21 @@ public final class LsRefsV2Request { @Nullable private final String agent; + private final String clientSID; + @NonNull private final List<String> serverOptions; private LsRefsV2Request(List<String> refPrefixes, boolean symrefs, boolean peel, @Nullable String agent, - @NonNull List<String> serverOptions) { + @NonNull List<String> serverOptions, + @Nullable String clientSID) { this.refPrefixes = refPrefixes; this.symrefs = symrefs; this.peel = peel; this.agent = agent; this.serverOptions = requireNonNull(serverOptions); + this.clientSID = clientSID; } /** @return ref prefixes that the client requested. */ @@ -75,6 +79,16 @@ public String getAgent() { } /** + * @return session-id as reported by the client + * + * @since 6.4 + */ + @Nullable + public String getClientSID() { + return clientSID; + } + + /** * Get application-specific options provided by the client using * --server-option. * <p> @@ -109,6 +123,8 @@ public static final class Builder { private String agent; + private String clientSID; + private Builder() { } @@ -171,11 +187,28 @@ public Builder setAgent(@Nullable String value) { return this; } + /** + * Value of a session-id line received after the command and before the + * arguments. E.g. "session-id=a.b.c" should set "a.b.c". + * + * @param value + * the client-supplied session-id capability, without leading + * "session-id=" + * @return this builder + * + * @since 6.4 + */ + public Builder setClientSID(@Nullable String value) { + clientSID = value; + return this; + } + /** @return LsRefsV2Request */ public LsRefsV2Request build() { return new LsRefsV2Request( Collections.unmodifiableList(refPrefixes), symrefs, peel, - agent, Collections.unmodifiableList(serverOptions)); + agent, Collections.unmodifiableList(serverOptions), + clientSID); } } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java index 21a4925..9d05551 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java
@@ -152,6 +152,7 @@ FetchV0Request recvWants(PacketLineIn pckIn) FirstWant firstLine = FirstWant.fromLine(line); reqBuilder.addClientCapabilities(firstLine.getCapabilities()); reqBuilder.setAgent(firstLine.getAgent()); + reqBuilder.setClientSID(firstLine.getClientSID()); line = firstLine.getLine(); } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java index b38deb6..c4129ff 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
@@ -20,6 +20,7 @@ import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_WAIT_FOR_DONE; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SESSION_ID; import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_DEEPEN; import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_DEEPEN_NOT; import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_DEEPEN_SINCE; @@ -63,10 +64,12 @@ final class ProtocolV2Parser { */ private static String consumeCapabilities(PacketLineIn pckIn, Consumer<String> serverOptionConsumer, - Consumer<String> agentConsumer) throws IOException { + Consumer<String> agentConsumer, + Consumer<String> clientSIDConsumer) throws IOException { String serverOptionPrefix = OPTION_SERVER_OPTION + '='; String agentPrefix = OPTION_AGENT + '='; + String clientSIDPrefix = OPTION_SESSION_ID + '='; String line = pckIn.readString(); while (!PacketLineIn.isDelimiter(line) && !PacketLineIn.isEnd(line)) { @@ -75,6 +78,9 @@ private static String consumeCapabilities(PacketLineIn pckIn, .accept(line.substring(serverOptionPrefix.length())); } else if (line.startsWith(agentPrefix)) { agentConsumer.accept(line.substring(agentPrefix.length())); + } else if (line.startsWith(clientSIDPrefix)) { + clientSIDConsumer + .accept(line.substring(clientSIDPrefix.length())); } else { // Unrecognized capability. Ignore it. } @@ -108,7 +114,8 @@ FetchV2Request parseFetchRequest(PacketLineIn pckIn) String line = consumeCapabilities(pckIn, serverOption -> reqBuilder.addServerOption(serverOption), - agent -> reqBuilder.setAgent(agent)); + agent -> reqBuilder.setAgent(agent), + clientSID -> reqBuilder.setClientSID(clientSID)); if (PacketLineIn.isEnd(line)) { return reqBuilder.build(); @@ -235,7 +242,8 @@ LsRefsV2Request parseLsRefsRequest(PacketLineIn pckIn) String line = consumeCapabilities(pckIn, serverOption -> builder.addServerOption(serverOption), - agent -> builder.setAgent(agent)); + agent -> builder.setAgent(agent), + clientSID -> builder.setClientSID(clientSID)); if (PacketLineIn.isEnd(line)) { return builder.build();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java index b70eedc..816cec8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -22,6 +22,7 @@ import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT; import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_ERR; import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_SHALLOW; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SESSION_ID; import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA; import static org.eclipse.jgit.transport.SideBandOutputStream.CH_ERROR; import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS; @@ -35,6 +36,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -113,7 +115,15 @@ public String getLine() { /** @return capabilities parsed from the line. */ public Set<String> getCapabilities() { - return command.getCapabilities(); + Set<String> reconstructedCapabilites = new HashSet<>(); + for (Map.Entry<String, String> e : command.getCapabilities() + .entrySet()) { + String cap = e.getValue() == null ? e.getKey() + : e.getKey() + "=" + e.getValue(); //$NON-NLS-1$ + reconstructedCapabilites.add(cap); + } + + return reconstructedCapabilites; } } @@ -166,6 +176,9 @@ public Set<String> getCapabilities() { private boolean allowQuiet = true; + /** Should the server advertise and accept the session-id capability. */ + private boolean allowReceiveClientSID; + /** Identity to record action as within the reflog. */ private PersonIdent refLogIdent; @@ -215,7 +228,10 @@ public Set<String> getCapabilities() { private Set<ObjectId> advertisedHaves; /** Capabilities requested by the client. */ - private Set<String> enabledCapabilities; + private Map<String, String> enabledCapabilities; + + /** Session ID sent from the client. Null if none was received. */ + private String clientSID; String userAgent; @@ -296,6 +312,7 @@ public ReceivePack(Repository into) { TransferConfig tc = db.getConfig().get(TransferConfig.KEY); objectChecker = tc.newReceiveObjectChecker(); + allowReceiveClientSID = tc.isAllowReceiveClientSID(); ReceiveConfig rc = db.getConfig().get(ReceiveConfig::new); allowCreates = rc.allowCreates; @@ -886,7 +903,7 @@ public void setMaxPackSizeLimit(long limit) { */ public boolean isSideBand() throws RequestNotYetReadException { checkRequestWasRead(); - return enabledCapabilities.contains(CAPABILITY_SIDE_BAND_64K); + return enabledCapabilities.containsKey(CAPABILITY_SIDE_BAND_64K); } /** @@ -987,7 +1004,11 @@ private PushCertificateParser getPushCertificateParser() { * @since 4.0 */ public String getPeerUserAgent() { - return UserAgent.getAgent(enabledCapabilities, userAgent); + if (enabledCapabilities == null || enabledCapabilities.isEmpty()) { + return userAgent; + } + + return enabledCapabilities.getOrDefault(OPTION_AGENT, userAgent); } /** @@ -1182,7 +1203,7 @@ protected void init(final InputStream input, final OutputStream output, pckOut = new PacketLineOut(rawOut); pckOut.setFlushOnEnd(false); - enabledCapabilities = new HashSet<>(); + enabledCapabilities = new HashMap<>(); commands = new ArrayList<>(); } @@ -1267,25 +1288,33 @@ public void sendAdvertisedRefs(RefAdvertiser adv) adv.advertiseCapability(CAPABILITY_SIDE_BAND_64K); adv.advertiseCapability(CAPABILITY_DELETE_REFS); adv.advertiseCapability(CAPABILITY_REPORT_STATUS); - if (allowQuiet) + if (allowReceiveClientSID) { + adv.advertiseCapability(OPTION_SESSION_ID); + } + if (allowQuiet) { adv.advertiseCapability(CAPABILITY_QUIET); + } String nonce = getPushCertificateParser().getAdvertiseNonce(); if (nonce != null) { adv.advertiseCapability(nonce); } - if (db.getRefDatabase().performsAtomicTransactions()) + if (db.getRefDatabase().performsAtomicTransactions()) { adv.advertiseCapability(CAPABILITY_ATOMIC); - if (allowOfsDelta) + } + if (allowOfsDelta) { adv.advertiseCapability(CAPABILITY_OFS_DELTA); + } if (allowPushOptions) { adv.advertiseCapability(CAPABILITY_PUSH_OPTIONS); } adv.advertiseCapability(OPTION_AGENT, UserAgent.get()); adv.send(getAdvertisedOrDefaultRefs().values()); - for (ObjectId obj : advertisedHaves) + for (ObjectId obj : advertisedHaves) { adv.advertiseHave(obj); - if (adv.isEmpty()) + } + if (adv.isEmpty()) { adv.advertiseId(ObjectId.zeroId(), "capabilities^{}"); //$NON-NLS-1$ + } adv.end(); } @@ -1437,6 +1466,9 @@ private void enableCapabilities() { usePushOptions = isCapabilityEnabled(CAPABILITY_PUSH_OPTIONS); sideBand = isCapabilityEnabled(CAPABILITY_SIDE_BAND_64K); quiet = allowQuiet && isCapabilityEnabled(CAPABILITY_QUIET); + + clientSID = enabledCapabilities.get(OPTION_SESSION_ID); + if (sideBand) { OutputStream out = rawOut; @@ -1457,7 +1489,7 @@ private void enableCapabilities() { * @return true if the peer requested the capability to be enabled. */ private boolean isCapabilityEnabled(String name) { - return enabledCapabilities.contains(name); + return enabledCapabilities.containsKey(name); } private void checkRequestWasRead() { @@ -2118,6 +2150,14 @@ public void setEchoCommandFailures(boolean echo) { } /** + * @return The client session-id. + * @since 6.4 + */ + public String getClientSID() { + return clientSID; + } + + /** * Execute the receive task on the socket. * * @param input
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java index 02be434..805166a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
@@ -125,6 +125,8 @@ static ProtocolVersion parse(@Nullable String name) { private final boolean advertiseWaitForDone; private final boolean advertiseObjectInfo; + private final boolean allowReceiveClientSID; + final @Nullable ProtocolVersion protocolVersion; final String[] hideRefs; @@ -214,6 +216,8 @@ public TransferConfig(Config rc) { "advertisewaitfordone", false); advertiseObjectInfo = rc.getBoolean("uploadpack", "advertiseobjectinfo", false); + allowReceiveClientSID = rc.getBoolean("transfer", "advertisesid", + false); } /** @@ -329,6 +333,14 @@ public boolean isAdvertiseObjectInfo() { } /** + * @return true to advertise and receive session-id capability + * @since 6.4 + */ + public boolean isAllowReceiveClientSID() { + return allowReceiveClientSID; + } + + /** * Get {@link org.eclipse.jgit.transport.RefFilter} respecting configured * hidden refs. *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index 65dbf12..a7ce1d7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -34,6 +34,7 @@ import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDEBAND_ALL; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SESSION_ID; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_WAIT_FOR_DONE; import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_ACK; @@ -1382,6 +1383,10 @@ private List<String> getV2CapabilityAdvertisement() { : "") + OPTION_SHALLOW); caps.add(CAPABILITY_SERVER_OPTION); + if (transferConfig.isAllowReceiveClientSID()) { + caps.add(OPTION_SESSION_ID); + } + return caps; } @@ -1700,6 +1705,21 @@ public String getPeerUserAgent() { return userAgent; } + /** + * Get the session ID if received from the client. + * + * @return The session ID if it has been received from the client. + * @since 6.4 + */ + @Nullable + public String getClientSID() { + if (currentRequest == null) { + return null; + } + + return currentRequest.getClientSID(); + } + private boolean negotiate(FetchRequest req, PackStatistics.Accumulator accumulator, PacketLineOut pckOut)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UserAgent.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UserAgent.java index 604eb3a..df98d0c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UserAgent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UserAgent.java
@@ -91,6 +91,15 @@ public static void set(String agent) { userAgent = StringUtils.isEmptyOrNull(agent) ? null : clean(agent); } + /** + * + * @param options + * @param transportAgent + * @return The transport agent. + * @deprecated Capabilities with <key>=<value> shape are now parsed + * alongside other capabilities in the ReceivePack flow. + */ + @Deprecated static String getAgent(Set<String> options, String transportAgent) { if (options == null || options.isEmpty()) { return transportAgent; @@ -105,6 +114,14 @@ static String getAgent(Set<String> options, String transportAgent) { return transportAgent; } + /** + * + * @param options + * @return True if the transport agent is set. False otherwise. + * @deprecated Capabilities with <key>=<value> shape are now parsed + * alongside other capabilities in the ReceivePack flow. + */ + @Deprecated static boolean hasAgent(Set<String> options) { return getAgent(options, null) != null; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index e8f38d8..aef9e64 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -299,14 +299,19 @@ public static final class FileStoreAttributes { static { // Shut down the SAVE_RUNNER on System.exit() - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - try { - SAVE_RUNNER.shutdownNow(); - SAVE_RUNNER.awaitTermination(100, TimeUnit.MILLISECONDS); - } catch (Exception e) { - // Ignore; we're shutting down - } - })); + try { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + SAVE_RUNNER.shutdownNow(); + SAVE_RUNNER.awaitTermination(100, + TimeUnit.MILLISECONDS); + } catch (Exception e) { + // Ignore; we're shutting down + } + })); + } catch (IllegalStateException e) { + // ignore - may fail if shutdown is already in progress + } } /**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java index 1420add..87993d2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2017, Google Inc. and others + * Copyright (C) 2022, Matthias Sohn <matthias.sohn@sap.com> 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 @@ -7,99 +7,96 @@ * * SPDX-License-Identifier: BSD-3-Clause */ - package org.eclipse.jgit.util.sha1; -import static java.lang.Integer.lowestOneBit; -import static java.lang.Integer.numberOfTrailingZeros; -import static java.lang.Integer.rotateLeft; -import static java.lang.Integer.rotateRight; +import java.io.IOException; +import java.security.MessageDigest; -import java.text.MessageFormat; -import java.util.Arrays; - -import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.MutableObjectId; import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.util.NB; import org.eclipse.jgit.util.SystemReader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * Pure Java implementation of SHA-1 from FIPS 180-1 / RFC 3174. - * + * SHA-1 interface from FIPS 180-1 / RFC 3174 with optional collision detection. + * Some implementations may not support collision detection. * <p> * See <a href="https://tools.ietf.org/html/rfc3174">RFC 3174</a>. - * <p> - * Unlike MessageDigest, this implementation includes the algorithm used by - * {@code sha1dc} to detect cryptanalytic collision attacks against SHA-1, such - * as the one used by <a href="https://shattered.it/">SHAttered</a>. See - * <a href="https://github.com/cr-marcstevens/sha1collisiondetection"> - * sha1collisiondetection</a> for more information. - * <p> - * When detectCollision is true (default), this implementation throws - * {@link org.eclipse.jgit.util.sha1.Sha1CollisionException} from any digest - * method if a potential collision was detected. - * - * @since 4.7 */ -public class SHA1 { - private static final Logger LOG = LoggerFactory.getLogger(SHA1.class); - private static final boolean DETECT_COLLISIONS; +public abstract class SHA1 { + /** + * SHA1 implementations available in JGit + */ + public enum Sha1Implementation { + /** + * {@link SHA1Java} implemented in Java, supports collision detection. + */ + JAVA(SHA1Java.class), + /** + * Native implementation based on JDK's {@link MessageDigest}. + */ + JDKNATIVE(SHA1Native.class); - static { - SystemReader sr = SystemReader.getInstance(); - String v = sr.getProperty("org.eclipse.jgit.util.sha1.detectCollision"); //$NON-NLS-1$ - DETECT_COLLISIONS = v != null ? Boolean.parseBoolean(v) : true; + private final String implClassName; + + private Sha1Implementation(Class implClass) { + this.implClassName = implClass.getName(); + } + + @Override + public String toString() { + return implClassName; + } + } + + private static final Sha1Implementation SHA1_IMPLEMENTATION = fromConfig(); + + private static Sha1Implementation fromConfig() { + try { + return SystemReader.getInstance().getUserConfig().getEnum( + ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.SHA1_IMPLEMENTATION, + Sha1Implementation.JAVA); + } catch (ConfigInvalidException | IOException e) { + return Sha1Implementation.JAVA; + } + } + + private static Sha1Implementation getImplementation() { + String fromSystemProperty = System + .getProperty("org.eclipse.jgit.util.sha1.implementation"); //$NON-NLS-1$ + if (fromSystemProperty == null) { + return SHA1_IMPLEMENTATION; + } + if (fromSystemProperty + .equalsIgnoreCase(Sha1Implementation.JAVA.name())) { + return Sha1Implementation.JAVA; + } + if (fromSystemProperty + .equalsIgnoreCase(Sha1Implementation.JDKNATIVE.name())) { + return Sha1Implementation.JDKNATIVE; + } + return SHA1_IMPLEMENTATION; } /** * Create a new context to compute a SHA-1 hash of data. + * <p> + * If {@code core.sha1Implementation = jdkNative} in the user level global + * git configuration or the system property + * {@code org.eclipse.jgit.util.sha1.implementation = jdkNative} it will + * create an object using the implementation in the JDK. If both are set the + * system property takes precedence. Otherwise the pure Java implementation + * will be used which supports collision detection but is slower. * * @return a new context to compute a SHA-1 hash of data. */ public static SHA1 newInstance() { - return new SHA1(); - } - - private final State h = new State(); - private final int[] w = new int[80]; - - /** Buffer to accumulate partial blocks to 64 byte alignment. */ - private final byte[] buffer = new byte[64]; - - /** Total number of bytes in the message. */ - private long length; - - private boolean detectCollision = DETECT_COLLISIONS; - private boolean foundCollision; - - private final int[] w2 = new int[80]; - private final State state58 = new State(); - private final State state65 = new State(); - private final State hIn = new State(); - private final State hTmp = new State(); - - private SHA1() { - h.init(); - } - - /** - * Enable likely collision detection. - * <p> - * Default is {@code true}. - * <p> - * May also be set by system property: - * {@code -Dorg.eclipse.jgit.util.sha1.detectCollision=true}. - * - * @param detect - * a boolean. - * @return {@code this} - */ - public SHA1 setDetectCollision(boolean detect) { - detectCollision = detect; - return this; + if (getImplementation() == Sha1Implementation.JDKNATIVE) { + return new SHA1Native(); + } + return new SHA1Java(); } /** @@ -107,14 +104,7 @@ public SHA1 setDetectCollision(boolean detect) { * * @param b a byte. */ - public void update(byte b) { - int bufferLen = (int) (length & 63); - length++; - buffer[bufferLen] = b; - if (bufferLen == 63) { - compress(buffer, 0); - } - } + public abstract void update(byte b); /** * Update the digest computation by adding bytes to the message. @@ -122,9 +112,7 @@ public void update(byte b) { * @param in * input array of bytes. */ - public void update(byte[] in) { - update(in, 0, in.length); - } + public abstract void update(byte[] in); /** * Update the digest computation by adding bytes to the message. @@ -136,344 +124,7 @@ public void update(byte[] in) { * @param len * number of bytes to hash. */ - public void update(byte[] in, int p, int len) { - // SHA-1 compress can only process whole 64 byte blocks. - // Hold partial updates in buffer, whose length is the low bits. - int bufferLen = (int) (length & 63); - length += len; - - if (bufferLen > 0) { - int n = Math.min(64 - bufferLen, len); - System.arraycopy(in, p, buffer, bufferLen, n); - p += n; - len -= n; - if (bufferLen + n < 64) { - return; - } - compress(buffer, 0); - } - while (len >= 64) { - compress(in, p); - p += 64; - len -= 64; - } - if (len > 0) { - System.arraycopy(in, p, buffer, 0, len); - } - } - - private void compress(byte[] block, int p) { - initBlock(block, p); - int ubcDvMask = detectCollision ? UbcCheck.check(w) : 0; - compress(); - - while (ubcDvMask != 0) { - int b = numberOfTrailingZeros(lowestOneBit(ubcDvMask)); - UbcCheck.DvInfo dv = UbcCheck.DV[b]; - for (int i = 0; i < 80; i++) { - w2[i] = w[i] ^ dv.dm[i]; - } - recompress(dv.testt); - if (eq(hTmp, h)) { - foundCollision = true; - break; - } - ubcDvMask &= ~(1 << b); - } - } - - private void initBlock(byte[] block, int p) { - for (int t = 0; t < 16; t++) { - w[t] = NB.decodeInt32(block, p + (t << 2)); - } - - // RFC 3174 6.1.b, extend state vector to 80 words. - for (int t = 16; t < 80; t++) { - int x = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]; - w[t] = rotateLeft(x, 1); // S^1(...) - } - } - - private void compress() { - // Method 1 from RFC 3174 section 6.1. - // Method 2 (circular queue of 16 words) is slower. - int a = h.a, b = h.b, c = h.c, d = h.d, e = h.e; - - // @formatter:off - e += s1(a, b, c, d,w[ 0]); b = rotateLeft( b, 30); - d += s1(e, a, b, c,w[ 1]); a = rotateLeft( a, 30); - c += s1(d, e, a, b,w[ 2]); e = rotateLeft( e, 30); - b += s1(c, d, e, a,w[ 3]); d = rotateLeft( d, 30); - a += s1(b, c, d, e,w[ 4]); c = rotateLeft( c, 30); - e += s1(a, b, c, d,w[ 5]); b = rotateLeft( b, 30); - d += s1(e, a, b, c,w[ 6]); a = rotateLeft( a, 30); - c += s1(d, e, a, b,w[ 7]); e = rotateLeft( e, 30); - b += s1(c, d, e, a,w[ 8]); d = rotateLeft( d, 30); - a += s1(b, c, d, e,w[ 9]); c = rotateLeft( c, 30); - e += s1(a, b, c, d,w[ 10]); b = rotateLeft( b, 30); - d += s1(e, a, b, c,w[ 11]); a = rotateLeft( a, 30); - c += s1(d, e, a, b,w[ 12]); e = rotateLeft( e, 30); - b += s1(c, d, e, a,w[ 13]); d = rotateLeft( d, 30); - a += s1(b, c, d, e,w[ 14]); c = rotateLeft( c, 30); - e += s1(a, b, c, d,w[ 15]); b = rotateLeft( b, 30); - d += s1(e, a, b, c,w[ 16]); a = rotateLeft( a, 30); - c += s1(d, e, a, b,w[ 17]); e = rotateLeft( e, 30); - b += s1(c, d, e, a,w[ 18]); d = rotateLeft( d, 30); - a += s1(b, c, d, e,w[ 19]); c = rotateLeft( c, 30); - - e += s2(a, b, c, d,w[ 20]); b = rotateLeft( b, 30); - d += s2(e, a, b, c,w[ 21]); a = rotateLeft( a, 30); - c += s2(d, e, a, b,w[ 22]); e = rotateLeft( e, 30); - b += s2(c, d, e, a,w[ 23]); d = rotateLeft( d, 30); - a += s2(b, c, d, e,w[ 24]); c = rotateLeft( c, 30); - e += s2(a, b, c, d,w[ 25]); b = rotateLeft( b, 30); - d += s2(e, a, b, c,w[ 26]); a = rotateLeft( a, 30); - c += s2(d, e, a, b,w[ 27]); e = rotateLeft( e, 30); - b += s2(c, d, e, a,w[ 28]); d = rotateLeft( d, 30); - a += s2(b, c, d, e,w[ 29]); c = rotateLeft( c, 30); - e += s2(a, b, c, d,w[ 30]); b = rotateLeft( b, 30); - d += s2(e, a, b, c,w[ 31]); a = rotateLeft( a, 30); - c += s2(d, e, a, b,w[ 32]); e = rotateLeft( e, 30); - b += s2(c, d, e, a,w[ 33]); d = rotateLeft( d, 30); - a += s2(b, c, d, e,w[ 34]); c = rotateLeft( c, 30); - e += s2(a, b, c, d,w[ 35]); b = rotateLeft( b, 30); - d += s2(e, a, b, c,w[ 36]); a = rotateLeft( a, 30); - c += s2(d, e, a, b,w[ 37]); e = rotateLeft( e, 30); - b += s2(c, d, e, a,w[ 38]); d = rotateLeft( d, 30); - a += s2(b, c, d, e,w[ 39]); c = rotateLeft( c, 30); - - e += s3(a, b, c, d,w[ 40]); b = rotateLeft( b, 30); - d += s3(e, a, b, c,w[ 41]); a = rotateLeft( a, 30); - c += s3(d, e, a, b,w[ 42]); e = rotateLeft( e, 30); - b += s3(c, d, e, a,w[ 43]); d = rotateLeft( d, 30); - a += s3(b, c, d, e,w[ 44]); c = rotateLeft( c, 30); - e += s3(a, b, c, d,w[ 45]); b = rotateLeft( b, 30); - d += s3(e, a, b, c,w[ 46]); a = rotateLeft( a, 30); - c += s3(d, e, a, b,w[ 47]); e = rotateLeft( e, 30); - b += s3(c, d, e, a,w[ 48]); d = rotateLeft( d, 30); - a += s3(b, c, d, e,w[ 49]); c = rotateLeft( c, 30); - e += s3(a, b, c, d,w[ 50]); b = rotateLeft( b, 30); - d += s3(e, a, b, c,w[ 51]); a = rotateLeft( a, 30); - c += s3(d, e, a, b,w[ 52]); e = rotateLeft( e, 30); - b += s3(c, d, e, a,w[ 53]); d = rotateLeft( d, 30); - a += s3(b, c, d, e,w[ 54]); c = rotateLeft( c, 30); - e += s3(a, b, c, d,w[ 55]); b = rotateLeft( b, 30); - d += s3(e, a, b, c,w[ 56]); a = rotateLeft( a, 30); - c += s3(d, e, a, b,w[ 57]); e = rotateLeft( e, 30); - state58.save(a, b, c, d, e); - b += s3(c, d, e, a,w[ 58]); d = rotateLeft( d, 30); - a += s3(b, c, d, e,w[ 59]); c = rotateLeft( c, 30); - - e += s4(a, b, c, d,w[ 60]); b = rotateLeft( b, 30); - d += s4(e, a, b, c,w[ 61]); a = rotateLeft( a, 30); - c += s4(d, e, a, b,w[ 62]); e = rotateLeft( e, 30); - b += s4(c, d, e, a,w[ 63]); d = rotateLeft( d, 30); - a += s4(b, c, d, e,w[ 64]); c = rotateLeft( c, 30); - state65.save(a, b, c, d, e); - e += s4(a, b, c, d,w[ 65]); b = rotateLeft( b, 30); - d += s4(e, a, b, c,w[ 66]); a = rotateLeft( a, 30); - c += s4(d, e, a, b,w[ 67]); e = rotateLeft( e, 30); - b += s4(c, d, e, a,w[ 68]); d = rotateLeft( d, 30); - a += s4(b, c, d, e,w[ 69]); c = rotateLeft( c, 30); - e += s4(a, b, c, d,w[ 70]); b = rotateLeft( b, 30); - d += s4(e, a, b, c,w[ 71]); a = rotateLeft( a, 30); - c += s4(d, e, a, b,w[ 72]); e = rotateLeft( e, 30); - b += s4(c, d, e, a,w[ 73]); d = rotateLeft( d, 30); - a += s4(b, c, d, e,w[ 74]); c = rotateLeft( c, 30); - e += s4(a, b, c, d,w[ 75]); b = rotateLeft( b, 30); - d += s4(e, a, b, c,w[ 76]); a = rotateLeft( a, 30); - c += s4(d, e, a, b,w[ 77]); e = rotateLeft( e, 30); - b += s4(c, d, e, a,w[ 78]); d = rotateLeft( d, 30); - a += s4(b, c, d, e,w[ 79]); c = rotateLeft( c, 30); - - // @formatter:on - h.save(h.a + a, h.b + b, h.c + c, h.d + d, h.e + e); - } - - private void recompress(int t) { - State s; - switch (t) { - case 58: - s = state58; - break; - case 65: - s = state65; - break; - default: - throw new IllegalStateException(); - } - int a = s.a, b = s.b, c = s.c, d = s.d, e = s.e; - - // @formatter:off - if (t == 65) { - { c = rotateRight( c, 30); a -= s4(b, c, d, e,w2[ 64]);} - { d = rotateRight( d, 30); b -= s4(c, d, e, a,w2[ 63]);} - { e = rotateRight( e, 30); c -= s4(d, e, a, b,w2[ 62]);} - { a = rotateRight( a, 30); d -= s4(e, a, b, c,w2[ 61]);} - { b = rotateRight( b, 30); e -= s4(a, b, c, d,w2[ 60]);} - - { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 59]);} - { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 58]);} - } - { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 57]);} - { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 56]);} - { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 55]);} - { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 54]);} - { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 53]);} - { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 52]);} - { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 51]);} - { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 50]);} - { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 49]);} - { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 48]);} - { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 47]);} - { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 46]);} - { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 45]);} - { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 44]);} - { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 43]);} - { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 42]);} - { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 41]);} - { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 40]);} - - { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 39]);} - { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 38]);} - { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 37]);} - { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 36]);} - { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 35]);} - { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 34]);} - { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 33]);} - { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 32]);} - { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 31]);} - { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 30]);} - { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 29]);} - { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 28]);} - { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 27]);} - { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 26]);} - { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 25]);} - { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 24]);} - { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 23]);} - { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 22]);} - { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 21]);} - { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 20]);} - - { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 19]);} - { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 18]);} - { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 17]);} - { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 16]);} - { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 15]);} - { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 14]);} - { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 13]);} - { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 12]);} - { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 11]);} - { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 10]);} - { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 9]);} - { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 8]);} - { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 7]);} - { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 6]);} - { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 5]);} - { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 4]);} - { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 3]);} - { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 2]);} - { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 1]);} - { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 0]);} - - hIn.save(a, b, c, d, e); - a = s.a; b = s.b; c = s.c; d = s.d; e = s.e; - - if (t == 58) { - { b += s3(c, d, e, a,w2[ 58]); d = rotateLeft( d, 30);} - { a += s3(b, c, d, e,w2[ 59]); c = rotateLeft( c, 30);} - - { e += s4(a, b, c, d,w2[ 60]); b = rotateLeft( b, 30);} - { d += s4(e, a, b, c,w2[ 61]); a = rotateLeft( a, 30);} - { c += s4(d, e, a, b,w2[ 62]); e = rotateLeft( e, 30);} - { b += s4(c, d, e, a,w2[ 63]); d = rotateLeft( d, 30);} - { a += s4(b, c, d, e,w2[ 64]); c = rotateLeft( c, 30);} - } - { e += s4(a, b, c, d,w2[ 65]); b = rotateLeft( b, 30);} - { d += s4(e, a, b, c,w2[ 66]); a = rotateLeft( a, 30);} - { c += s4(d, e, a, b,w2[ 67]); e = rotateLeft( e, 30);} - { b += s4(c, d, e, a,w2[ 68]); d = rotateLeft( d, 30);} - { a += s4(b, c, d, e,w2[ 69]); c = rotateLeft( c, 30);} - { e += s4(a, b, c, d,w2[ 70]); b = rotateLeft( b, 30);} - { d += s4(e, a, b, c,w2[ 71]); a = rotateLeft( a, 30);} - { c += s4(d, e, a, b,w2[ 72]); e = rotateLeft( e, 30);} - { b += s4(c, d, e, a,w2[ 73]); d = rotateLeft( d, 30);} - { a += s4(b, c, d, e,w2[ 74]); c = rotateLeft( c, 30);} - { e += s4(a, b, c, d,w2[ 75]); b = rotateLeft( b, 30);} - { d += s4(e, a, b, c,w2[ 76]); a = rotateLeft( a, 30);} - { c += s4(d, e, a, b,w2[ 77]); e = rotateLeft( e, 30);} - { b += s4(c, d, e, a,w2[ 78]); d = rotateLeft( d, 30);} - { a += s4(b, c, d, e,w2[ 79]); c = rotateLeft( c, 30);} - - // @formatter:on - hTmp.save(hIn.a + a, hIn.b + b, hIn.c + c, hIn.d + d, hIn.e + e); - } - - private static int s1(int a, int b, int c, int d, int w_t) { - return rotateLeft(a, 5) - // f: 0 <= t <= 19 - + ((b & c) | ((~b) & d)) - + 0x5A827999 + w_t; - } - - private static int s2(int a, int b, int c, int d, int w_t) { - return rotateLeft(a, 5) - // f: 20 <= t <= 39 - + (b ^ c ^ d) - + 0x6ED9EBA1 + w_t; - } - - private static int s3(int a, int b, int c, int d, int w_t) { - return rotateLeft(a, 5) - // f: 40 <= t <= 59 - + ((b & c) | (b & d) | (c & d)) - + 0x8F1BBCDC + w_t; - } - - private static int s4(int a, int b, int c, int d, int w_t) { - return rotateLeft(a, 5) - // f: 60 <= t <= 79 - + (b ^ c ^ d) - + 0xCA62C1D6 + w_t; - } - - private static boolean eq(State q, State r) { - return q.a == r.a - && q.b == r.b - && q.c == r.c - && q.d == r.d - && q.e == r.e; - } - - private void finish() { - int bufferLen = (int) (length & 63); - if (bufferLen > 55) { - // Last block is too small; pad, compress, pad another block. - buffer[bufferLen++] = (byte) 0x80; - Arrays.fill(buffer, bufferLen, 64, (byte) 0); - compress(buffer, 0); - Arrays.fill(buffer, 0, 56, (byte) 0); - } else { - // Last block can hold padding and length. - buffer[bufferLen++] = (byte) 0x80; - Arrays.fill(buffer, bufferLen, 56, (byte) 0); - } - - // SHA-1 appends the length of the message in bits after the - // padding block (above). Here length is in bytes. Multiply by - // 8 by shifting by 3 as part of storing the 64 bit byte length - // into the two words expected in the trailer. - NB.encodeInt32(buffer, 56, (int) (length >>> (32 - 3))); - NB.encodeInt32(buffer, 60, (int) (length << 3)); - compress(buffer, 0); - - if (foundCollision) { - ObjectId id = h.toObjectId(); - LOG.warn(MessageFormat.format(JGitText.get().sha1CollisionDetected, - id.name())); - throw new Sha1CollisionException(id); - } - } + public abstract void update(byte[] in, int p, int len); /** * Finish the digest and return the resulting hash. @@ -484,17 +135,7 @@ private void finish() { * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException * if a collision was detected and safeHash is false. */ - public byte[] digest() throws Sha1CollisionException { - finish(); - - byte[] b = new byte[20]; - NB.encodeInt32(b, 0, h.a); - NB.encodeInt32(b, 4, h.b); - NB.encodeInt32(b, 8, h.c); - NB.encodeInt32(b, 12, h.d); - NB.encodeInt32(b, 16, h.e); - return b; - } + public abstract byte[] digest() throws Sha1CollisionException; /** * Finish the digest and return the resulting hash. @@ -505,10 +146,7 @@ private void finish() { * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException * if a collision was detected and safeHash is false. */ - public ObjectId toObjectId() throws Sha1CollisionException { - finish(); - return h.toObjectId(); - } + public abstract ObjectId toObjectId() throws Sha1CollisionException; /** * Finish the digest and return the resulting hash. @@ -520,60 +158,42 @@ public ObjectId toObjectId() throws Sha1CollisionException { * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException * if a collision was detected and safeHash is false. */ - public void digest(MutableObjectId id) throws Sha1CollisionException { - finish(); - id.set(h.a, h.b, h.c, h.d, h.e); - } - - /** - * Check if a collision was detected. - * - * <p> - * This method only returns an accurate result after the digest was obtained - * through {@link #digest()}, {@link #digest(MutableObjectId)} or - * {@link #toObjectId()}, as the hashing function must finish processing to - * know the final state. - * - * @return {@code true} if a likely collision was detected. - */ - public boolean hasCollision() { - return foundCollision; - } + public abstract void digest(MutableObjectId id) + throws Sha1CollisionException; /** * Reset this instance to compute another hash. * * @return {@code this}. */ - public SHA1 reset() { - h.init(); - length = 0; - foundCollision = false; - return this; - } + public abstract SHA1 reset(); - private static final class State { - int a; - int b; - int c; - int d; - int e; + /** + * Enable likely collision detection. + * <p> + * Default for implementations supporting collision detection is + * {@code true}. + * <p> + * Implementations not supporting collision detection ignore calls to this + * method. + * + * @param detect + * a boolean. + * @return {@code this} + */ + public abstract SHA1 setDetectCollision(boolean detect); - final void init() { - // Magic initialization constants defined by FIPS180. - save(0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0); - } - - final void save(int a1, int b1, int c1, int d1, int e1) { - a = a1; - b = b1; - c = c1; - d = d1; - e = e1; - } - - ObjectId toObjectId() { - return new ObjectId(a, b, c, d, e); - } - } -} + /** + * Check if a collision was detected. This method only returns an accurate + * result after the digest was obtained through {@link #digest()}, + * {@link #digest(MutableObjectId)} or {@link #toObjectId()}, as the hashing + * function must finish processing to know the final state. + * <p> + * Implementations not supporting collision detection always return + * {@code false}. + * <p> + * + * @return {@code true} if a likely collision was detected. + */ + public abstract boolean hasCollision(); +} \ No newline at end of file
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1Java.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1Java.java new file mode 100644 index 0000000..213ee97 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1Java.java
@@ -0,0 +1,579 @@ +/* + * Copyright (C) 2017, Google Inc. 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.util.sha1; + +import static java.lang.Integer.lowestOneBit; +import static java.lang.Integer.numberOfTrailingZeros; +import static java.lang.Integer.rotateLeft; +import static java.lang.Integer.rotateRight; + +import java.text.MessageFormat; +import java.util.Arrays; + +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.MutableObjectId; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.util.NB; +import org.eclipse.jgit.util.SystemReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Pure Java implementation of SHA-1 from FIPS 180-1 / RFC 3174. + * + * <p> + * See <a href="https://tools.ietf.org/html/rfc3174">RFC 3174</a>. + * <p> + * Unlike MessageDigest, this implementation includes the algorithm used by + * {@code sha1dc} to detect cryptanalytic collision attacks against SHA-1, such + * as the one used by <a href="https://shattered.it/">SHAttered</a>. See + * <a href="https://github.com/cr-marcstevens/sha1collisiondetection"> + * sha1collisiondetection</a> for more information. + * <p> + * When detectCollision is true (default), this implementation throws + * {@link org.eclipse.jgit.util.sha1.Sha1CollisionException} from any digest + * method if a potential collision was detected. + * + * @since 4.7 + */ +class SHA1Java extends SHA1 { + private static final Logger LOG = LoggerFactory.getLogger(SHA1Java.class); + private static final boolean DETECT_COLLISIONS; + + static { + SystemReader sr = SystemReader.getInstance(); + String v = sr.getProperty("org.eclipse.jgit.util.sha1.detectCollision"); //$NON-NLS-1$ + DETECT_COLLISIONS = v != null ? Boolean.parseBoolean(v) : true; + } + + private final State h = new State(); + private final int[] w = new int[80]; + + /** Buffer to accumulate partial blocks to 64 byte alignment. */ + private final byte[] buffer = new byte[64]; + + /** Total number of bytes in the message. */ + private long length; + + private boolean detectCollision = DETECT_COLLISIONS; + private boolean foundCollision; + + private final int[] w2 = new int[80]; + private final State state58 = new State(); + private final State state65 = new State(); + private final State hIn = new State(); + private final State hTmp = new State(); + + SHA1Java() { + h.init(); + } + + /** + * Enable likely collision detection. + * <p> + * Default is {@code true}. + * <p> + * May also be set by system property: + * {@code -Dorg.eclipse.jgit.util.sha1.detectCollision=true}. + * + * @param detect + * a boolean. + * @return {@code this} + */ + @Override + public SHA1 setDetectCollision(boolean detect) { + detectCollision = detect; + return this; + } + + /** + * Update the digest computation by adding a byte. + * + * @param b a byte. + */ + @Override + public void update(byte b) { + int bufferLen = (int) (length & 63); + length++; + buffer[bufferLen] = b; + if (bufferLen == 63) { + compress(buffer, 0); + } + } + + /** + * Update the digest computation by adding bytes to the message. + * + * @param in + * input array of bytes. + */ + @Override + public void update(byte[] in) { + update(in, 0, in.length); + } + + /** + * Update the digest computation by adding bytes to the message. + * + * @param in + * input array of bytes. + * @param p + * offset to start at from {@code in}. + * @param len + * number of bytes to hash. + */ + @Override + public void update(byte[] in, int p, int len) { + // SHA-1 compress can only process whole 64 byte blocks. + // Hold partial updates in buffer, whose length is the low bits. + int bufferLen = (int) (length & 63); + length += len; + + if (bufferLen > 0) { + int n = Math.min(64 - bufferLen, len); + System.arraycopy(in, p, buffer, bufferLen, n); + p += n; + len -= n; + if (bufferLen + n < 64) { + return; + } + compress(buffer, 0); + } + while (len >= 64) { + compress(in, p); + p += 64; + len -= 64; + } + if (len > 0) { + System.arraycopy(in, p, buffer, 0, len); + } + } + + private void compress(byte[] block, int p) { + initBlock(block, p); + int ubcDvMask = detectCollision ? UbcCheck.check(w) : 0; + compress(); + + while (ubcDvMask != 0) { + int b = numberOfTrailingZeros(lowestOneBit(ubcDvMask)); + UbcCheck.DvInfo dv = UbcCheck.DV[b]; + for (int i = 0; i < 80; i++) { + w2[i] = w[i] ^ dv.dm[i]; + } + recompress(dv.testt); + if (eq(hTmp, h)) { + foundCollision = true; + break; + } + ubcDvMask &= ~(1 << b); + } + } + + private void initBlock(byte[] block, int p) { + for (int t = 0; t < 16; t++) { + w[t] = NB.decodeInt32(block, p + (t << 2)); + } + + // RFC 3174 6.1.b, extend state vector to 80 words. + for (int t = 16; t < 80; t++) { + int x = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]; + w[t] = rotateLeft(x, 1); // S^1(...) + } + } + + private void compress() { + // Method 1 from RFC 3174 section 6.1. + // Method 2 (circular queue of 16 words) is slower. + int a = h.a, b = h.b, c = h.c, d = h.d, e = h.e; + + // @formatter:off + e += s1(a, b, c, d,w[ 0]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 1]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 2]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 3]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 4]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 5]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 6]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 7]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 8]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 9]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 10]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 11]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 12]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 13]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 14]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 15]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 16]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 17]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 18]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 19]); c = rotateLeft( c, 30); + + e += s2(a, b, c, d,w[ 20]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 21]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 22]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 23]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 24]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 25]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 26]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 27]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 28]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 29]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 30]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 31]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 32]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 33]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 34]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 35]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 36]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 37]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 38]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 39]); c = rotateLeft( c, 30); + + e += s3(a, b, c, d,w[ 40]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 41]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 42]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 43]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 44]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 45]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 46]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 47]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 48]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 49]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 50]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 51]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 52]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 53]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 54]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 55]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 56]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 57]); e = rotateLeft( e, 30); + state58.save(a, b, c, d, e); + b += s3(c, d, e, a,w[ 58]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 59]); c = rotateLeft( c, 30); + + e += s4(a, b, c, d,w[ 60]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 61]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 62]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 63]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 64]); c = rotateLeft( c, 30); + state65.save(a, b, c, d, e); + e += s4(a, b, c, d,w[ 65]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 66]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 67]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 68]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 69]); c = rotateLeft( c, 30); + e += s4(a, b, c, d,w[ 70]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 71]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 72]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 73]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 74]); c = rotateLeft( c, 30); + e += s4(a, b, c, d,w[ 75]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 76]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 77]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 78]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 79]); c = rotateLeft( c, 30); + + // @formatter:on + h.save(h.a + a, h.b + b, h.c + c, h.d + d, h.e + e); + } + + private void recompress(int t) { + State s; + switch (t) { + case 58: + s = state58; + break; + case 65: + s = state65; + break; + default: + throw new IllegalStateException(); + } + int a = s.a, b = s.b, c = s.c, d = s.d, e = s.e; + + // @formatter:off + if (t == 65) { + { c = rotateRight( c, 30); a -= s4(b, c, d, e,w2[ 64]);} + { d = rotateRight( d, 30); b -= s4(c, d, e, a,w2[ 63]);} + { e = rotateRight( e, 30); c -= s4(d, e, a, b,w2[ 62]);} + { a = rotateRight( a, 30); d -= s4(e, a, b, c,w2[ 61]);} + { b = rotateRight( b, 30); e -= s4(a, b, c, d,w2[ 60]);} + + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 59]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 58]);} + } + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 57]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 56]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 55]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 54]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 53]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 52]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 51]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 50]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 49]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 48]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 47]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 46]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 45]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 44]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 43]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 42]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 41]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 40]);} + + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 39]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 38]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 37]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 36]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 35]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 34]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 33]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 32]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 31]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 30]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 29]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 28]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 27]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 26]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 25]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 24]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 23]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 22]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 21]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 20]);} + + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 19]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 18]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 17]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 16]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 15]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 14]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 13]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 12]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 11]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 10]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 9]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 8]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 7]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 6]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 5]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 4]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 3]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 2]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 1]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 0]);} + + hIn.save(a, b, c, d, e); + a = s.a; b = s.b; c = s.c; d = s.d; e = s.e; + + if (t == 58) { + { b += s3(c, d, e, a,w2[ 58]); d = rotateLeft( d, 30);} + { a += s3(b, c, d, e,w2[ 59]); c = rotateLeft( c, 30);} + + { e += s4(a, b, c, d,w2[ 60]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 61]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 62]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 63]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 64]); c = rotateLeft( c, 30);} + } + { e += s4(a, b, c, d,w2[ 65]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 66]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 67]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 68]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 69]); c = rotateLeft( c, 30);} + { e += s4(a, b, c, d,w2[ 70]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 71]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 72]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 73]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 74]); c = rotateLeft( c, 30);} + { e += s4(a, b, c, d,w2[ 75]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 76]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 77]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 78]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 79]); c = rotateLeft( c, 30);} + + // @formatter:on + hTmp.save(hIn.a + a, hIn.b + b, hIn.c + c, hIn.d + d, hIn.e + e); + } + + private static int s1(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 0 <= t <= 19 + + ((b & c) | ((~b) & d)) + + 0x5A827999 + w_t; + } + + private static int s2(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 20 <= t <= 39 + + (b ^ c ^ d) + + 0x6ED9EBA1 + w_t; + } + + private static int s3(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 40 <= t <= 59 + + ((b & c) | (b & d) | (c & d)) + + 0x8F1BBCDC + w_t; + } + + private static int s4(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 60 <= t <= 79 + + (b ^ c ^ d) + + 0xCA62C1D6 + w_t; + } + + private static boolean eq(State q, State r) { + return q.a == r.a + && q.b == r.b + && q.c == r.c + && q.d == r.d + && q.e == r.e; + } + + private void finish() { + int bufferLen = (int) (length & 63); + if (bufferLen > 55) { + // Last block is too small; pad, compress, pad another block. + buffer[bufferLen++] = (byte) 0x80; + Arrays.fill(buffer, bufferLen, 64, (byte) 0); + compress(buffer, 0); + Arrays.fill(buffer, 0, 56, (byte) 0); + } else { + // Last block can hold padding and length. + buffer[bufferLen++] = (byte) 0x80; + Arrays.fill(buffer, bufferLen, 56, (byte) 0); + } + + // SHA-1 appends the length of the message in bits after the + // padding block (above). Here length is in bytes. Multiply by + // 8 by shifting by 3 as part of storing the 64 bit byte length + // into the two words expected in the trailer. + NB.encodeInt32(buffer, 56, (int) (length >>> (32 - 3))); + NB.encodeInt32(buffer, 60, (int) (length << 3)); + compress(buffer, 0); + + if (foundCollision) { + ObjectId id = h.toObjectId(); + LOG.warn(MessageFormat.format(JGitText.get().sha1CollisionDetected, + id.name())); + throw new Sha1CollisionException(id); + } + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @return the bytes for the resulting hash. + * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + @Override + public byte[] digest() throws Sha1CollisionException { + finish(); + + byte[] b = new byte[20]; + NB.encodeInt32(b, 0, h.a); + NB.encodeInt32(b, 4, h.b); + NB.encodeInt32(b, 8, h.c); + NB.encodeInt32(b, 12, h.d); + NB.encodeInt32(b, 16, h.e); + return b; + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @return the ObjectId for the resulting hash. + * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + @Override + public ObjectId toObjectId() throws Sha1CollisionException { + finish(); + return h.toObjectId(); + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @param id + * destination to copy the digest to. + * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + @Override + public void digest(MutableObjectId id) throws Sha1CollisionException { + finish(); + id.set(h.a, h.b, h.c, h.d, h.e); + } + + /** + * Check if a collision was detected. + * + * <p> + * This method only returns an accurate result after the digest was obtained + * through {@link #digest()}, {@link #digest(MutableObjectId)} or + * {@link #toObjectId()}, as the hashing function must finish processing to + * know the final state. + * + * @return {@code true} if a likely collision was detected. + */ + @Override + public boolean hasCollision() { + return foundCollision; + } + + /** + * Reset this instance to compute another hash. + * + * @return {@code this}. + */ + @Override + public SHA1 reset() { + h.init(); + length = 0; + foundCollision = false; + return this; + } + + private static final class State { + int a; + int b; + int c; + int d; + int e; + + final void init() { + // Magic initialization constants defined by FIPS180. + save(0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0); + } + + final void save(int a1, int b1, int c1, int d1, int e1) { + a = a1; + b = b1; + c = c1; + d = d1; + e = e1; + } + + ObjectId toObjectId() { + return new ObjectId(a, b, c, d, e); + } + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1Native.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1Native.java new file mode 100644 index 0000000..4599ac0 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1Native.java
@@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022, Matthias Sohn <matthias.sohn@sap.com> 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.util.sha1; + +import java.security.MessageDigest; + +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.MutableObjectId; +import org.eclipse.jgit.lib.ObjectId; + +/** + * SHA1 implementation using native implementation from JDK. It doesn't support + * collision detection but is faster than the pure Java implementation. + */ +class SHA1Native extends SHA1 { + + private final MessageDigest md; + + SHA1Native() { + md = Constants.newMessageDigest(); + } + + @Override + public void update(byte b) { + md.update(b); + } + + @Override + public void update(byte[] in) { + md.update(in); + } + + @Override + public void update(byte[] in, int p, int len) { + md.update(in, p, len); + } + + @Override + public byte[] digest() throws Sha1CollisionException { + return md.digest(); + } + + @Override + public ObjectId toObjectId() throws Sha1CollisionException { + return ObjectId.fromRaw(md.digest()); + } + + @Override + public void digest(MutableObjectId id) throws Sha1CollisionException { + id.fromRaw(md.digest()); + } + + @Override + public SHA1 reset() { + md.reset(); + return this; + } + + @Override + public SHA1 setDetectCollision(boolean detect) { + return this; + } + + @Override + public boolean hasCollision() { + return false; + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java index ce95ba5..fc8d7ab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java
@@ -16,7 +16,7 @@ import org.eclipse.jgit.lib.ObjectId; /** - * Thrown by {@link org.eclipse.jgit.util.sha1.SHA1} if it detects a likely hash + * Thrown by {@link org.eclipse.jgit.util.sha1.SHA1Java} if it detects a likely hash * collision. * * @since 4.7
diff --git a/pom.xml b/pom.xml index 4474505..8df5b53 100644 --- a/pom.xml +++ b/pom.xml
@@ -170,7 +170,7 @@ <maven-javadoc-plugin-version>3.3.1</maven-javadoc-plugin-version> <tycho-extras-version>2.6.0</tycho-extras-version> <gson-version>2.9.1</gson-version> - <bouncycastle-version>1.71</bouncycastle-version> + <bouncycastle-version>1.72</bouncycastle-version> <spotbugs-maven-plugin-version>4.3.0</spotbugs-maven-plugin-version> <maven-project-info-reports-plugin-version>3.1.2</maven-project-info-reports-plugin-version> <maven-jxr-plugin-version>3.1.1</maven-jxr-plugin-version>