diff --git a/WORKSPACE b/WORKSPACE index ccd7315d4..f78a159fb 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -243,55 +243,55 @@ maven_jar( sha1 = "431fc3cbc0ff81abdbfde070062741089c3ba874", ) -JETTY_VER = "9.4.44.v20210927" +JETTY_VER = "10.0.6" maven_jar( name = "jetty-servlet", artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER, - sha1 = "1cb43a0d74b7395c7207dbf3dc2ca97eac89f5fd", - src_sha1 = "2bbc54fc1835c963744a4e82ba2541e94fcbcf9b", + sha1 = "482165726bf54dd10ee7e2aeb4ae9481eee0c878", + src_sha1 = "8a8173a0bc6c0d215fc9fb9ba5fd50bae1690f9c", ) maven_jar( name = "jetty-security", artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER, - sha1 = "ecb80b8e008daa46e95e5691b2611d4007922497", - src_sha1 = "d67d4705a08d9b76592b3e177e2bb1aac968d832", + sha1 = "513f44ed9636ca5e0adefa0c0b81511065dfddd2", + src_sha1 = "2e7eb2edbf1592e15b338096651e379fea860859", ) maven_jar( name = "jetty-server", artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER, - sha1 = "0bf2de0d31925a8ca71ad80f721236850b636e0d", - src_sha1 = "3582cbf081cf3652f6507093585c2a0f3b8738bb", + sha1 = "125ee07e4d8182a6afca00d543f6a4dcc84f2678", + src_sha1 = "5c0789872ec6743ae893131ae81262aaefc87fe6", ) maven_jar( name = "jetty-http", artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER, - sha1 = "37f0e30cdc02128e40d095ad63cb18e10ecb7726", - src_sha1 = "7f1a6e3ab54e541f33b8ed100d553d4034d2e3a9", + sha1 = "4c8eed25d577002a6c0f9f3ef340eb581390f696", + src_sha1 = "ac7214d6202ee0cbc4bdbcf90c7906ca716e84e5", ) maven_jar( name = "jetty-io", artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER, - sha1 = "a2ec01e2b5552b777a3d7085163f80756ef8c1ce", - src_sha1 = "6262966b3cd10ff6b98f0bed428640bbbe4f7e79", + sha1 = "1ab82ae5dfdbb07f0ffa07f28274fdf30e3e96ee", + src_sha1 = "c59082f3a09c024fafc281f432b67432d398b8c0", ) maven_jar( name = "jetty-util", artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER, - sha1 = "3c7151c5a04a93119988b48a1577a972d90f8990", - src_sha1 = "f7f0420221772bc63ebae21571bb9925ca971a82", + sha1 = "4e2935749ea1c9fcabba61a857f8283c7f5f9885", + src_sha1 = "6baba651899c044e14ba37d43934950670d2aa4e", ) maven_jar( name = "jetty-util-ajax", artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER, - sha1 = "ed2f30e8eef939ab2825e607d83f82f85167e2c0", - src_sha1 = "1a48ae7a45683d20afb90784d1db314be2c73c92", + sha1 = "a801d4b5f5e906f134713ae82fd1ea10a15902c6", + src_sha1 = "f35f5525a5d30dc1237b85457d758d578e3ce8d0", ) BOUNCYCASTLE_VER = "1.69" diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml index effb8d494..3e0b32bf4 100644 --- a/org.eclipse.jgit.ant.test/pom.xml +++ b/org.eclipse.jgit.ant.test/pom.xml @@ -27,6 +27,10 @@ JUnit tests for the various ant tasks. + + true + + junit diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF index c7812e4fe..f4a25ee8f 100644 --- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF @@ -16,8 +16,8 @@ Export-Package: org.eclipse.jgit.http.server;version="6.0.0", javax.servlet.http" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-11 -Import-Package: javax.servlet;version="[2.5.0,3.2.0)", - javax.servlet.http;version="[2.5.0,3.2.0)", +Import-Package: javax.servlet;version="[2.5.0,5.0.0)", + javax.servlet.http;version="[2.5.0,5.0.0)", org.eclipse.jgit.annotations;version="[6.0.0,6.1.0)", org.eclipse.jgit.errors;version="[6.0.0,6.1.0)", org.eclipse.jgit.internal.storage.dfs;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF index 70a846de2..662f37c35 100644 --- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF @@ -7,27 +7,25 @@ Bundle-Version: 6.0.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-11 -Import-Package: javax.servlet;version="[2.5.0,3.2.0)", - javax.servlet.http;version="[2.5.0,3.2.0)", +Import-Package: javax.servlet;version="[2.5.0,5.0.0)", + javax.servlet.http;version="[2.5.0,5.0.0)", org.apache.commons.codec;version="[1.6.0,2.0.0)", org.apache.commons.codec.binary;version="[1.6.0,2.0.0)", org.apache.http;version="[4.3.0,5.0.0)", org.apache.http.client;version="[4.4.0,5.0.0)", org.apache.http.message;version="[4.3.0,5.0.0)", - org.eclipse.jetty.continuation;version="[9.4.5,10.0.0)", - org.eclipse.jetty.http;version="[9.4.5,10.0.0)", - org.eclipse.jetty.io;version="[9.4.5,10.0.0)", - org.eclipse.jetty.security;version="[9.4.5,10.0.0)", - org.eclipse.jetty.security.authentication;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server.handler;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server.nio;version="[9.4.5,10.0.0)", - org.eclipse.jetty.servlet;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.component;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.log;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.security;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.thread;version="[9.4.5,10.0.0)", + org.eclipse.jetty.http;version="[10.0.0,11.0.0)", + org.eclipse.jetty.io;version="[10.0.0,11.0.0)", + org.eclipse.jetty.security;version="[10.0.0,11.0.0)", + org.eclipse.jetty.security.authentication;version="[10.0.0,11.0.0)", + org.eclipse.jetty.server;version="[10.0.0,11.0.0)", + org.eclipse.jetty.server.handler;version="[10.0.0,11.0.0)", + org.eclipse.jetty.servlet;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.component;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.thread;version="[10.0.0,11.0.0)", org.eclipse.jgit.api;version="[6.0.0,6.1.0)", org.eclipse.jgit.errors;version="[6.0.0,6.1.0)", org.eclipse.jgit.http.server;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/transport/http/apache/HttpClientConnectionTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/transport/http/apache/HttpClientConnectionTest.java index 006a01e74..d38f7f3dd 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/transport/http/apache/HttpClientConnectionTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/transport/http/apache/HttpClientConnectionTest.java @@ -9,6 +9,13 @@ */ package org.eclipse.jgit.transport.http.apache; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.net.MalformedURLException; +import java.util.List; +import java.util.Locale; + import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.ProtocolVersion; @@ -16,13 +23,6 @@ import org.apache.http.message.AbstractHttpMessage; import org.junit.Test; -import java.net.MalformedURLException; -import java.util.List; -import java.util.Locale; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - public class HttpClientConnectionTest { @Test public void testGetHeaderFieldsAllowMultipleValues() diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF index e3e322262..6be5cdd09 100644 --- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF @@ -8,20 +8,19 @@ Bundle-Localization: plugin Bundle-Vendor: %Bundle-Vendor Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-11 -Import-Package: javax.servlet;version="[2.5.0,3.2.0)", - javax.servlet.http;version="[2.5.0,3.2.0)", +Import-Package: javax.servlet;version="[2.5.0,5.0.0)", + javax.servlet.http;version="[2.5.0,5.0.0)", org.apache.commons.logging;version="[1.1.1,2.0.0)", - org.eclipse.jetty.http;version="[9.4.5,10.0.0)", - org.eclipse.jetty.security;version="[9.4.5,10.0.0)", - org.eclipse.jetty.security.authentication;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server.handler;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server.nio;version="[9.4.5,10.0.0)", - org.eclipse.jetty.servlet;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.component;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.log;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.security;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.ssl;version="[9.4.5,10.0.0)", + org.eclipse.jetty.http;version="[10.0.0,11.0.0)", + org.eclipse.jetty.security;version="[10.0.0,11.0.0)", + org.eclipse.jetty.security.authentication;version="[10.0.0,11.0.0)", + org.eclipse.jetty.server;version="[10.0.0,11.0.0)", + org.eclipse.jetty.server.handler;version="[10.0.0,11.0.0)", + org.eclipse.jetty.servlet;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.component;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.ssl;version="[10.0.0,11.0.0)", org.eclipse.jgit.errors;version="[6.0.0,6.1.0)", org.eclipse.jgit.http.server;version="[6.0.0,6.1.0)", org.eclipse.jgit.internal.storage.file;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java index 0f052987e..36f2f2bc7 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java @@ -21,20 +21,23 @@ import java.net.UnknownHostException; import java.nio.file.Files; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.security.AbstractLoginService; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.ConstraintMapping; import org.eclipse.jetty.security.ConstraintSecurityHandler; +import org.eclipse.jetty.security.RolePrincipal; +import org.eclipse.jetty.security.UserPrincipal; import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SslConnectionFactory; @@ -143,13 +146,15 @@ public AppServer(int port, int sslPort) { } if (sslPort >= 0) { - SslContextFactory sslContextFactory = createTestSslContextFactory( - hostName); + SslContextFactory.Server sslContextFactory = createTestSslContextFactory( + hostName, ip); secureConfig = new HttpConfiguration(config); - secureConnector = new ServerConnector(server, - new SslConnectionFactory(sslContextFactory, - HttpVersion.HTTP_1_1.asString()), - new HttpConnectionFactory(secureConfig)); + secureConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConnectionFactory http11 = new HttpConnectionFactory( + secureConfig); + SslConnectionFactory tls = new SslConnectionFactory( + sslContextFactory, http11.getProtocol()); + secureConnector = new ServerConnector(server, tls, http11); secureConnector.setPort(sslPort); secureConnector.setHost(ip); } else { @@ -171,10 +176,11 @@ public AppServer(int port, int sslPort) { server.setHandler(log); } - private SslContextFactory createTestSslContextFactory(String hostName) { - SslContextFactory.Client factory = new SslContextFactory.Client(true); + private SslContextFactory.Server createTestSslContextFactory( + String hostName, String ip) { + SslContextFactory.Server factory = new SslContextFactory.Server(); - String dName = "CN=,OU=,O=,ST=,L=,C="; + String dName = "CN=localhost,OU=JGit,O=Eclipse,ST=Ontario,L=Toronto,C=CA"; try { File tmpDir = Files.createTempDirectory("jks").toFile(); @@ -190,6 +196,11 @@ private SslContextFactory createTestSslContextFactory(String hostName) { "-keystore", keyStore.getAbsolutePath(), // "-storepass", keyPassword, "-alias", hostName, // + "-ext", "bc=ca:true", // + "-ext", + String.format( + "san=ip:%s,ip:127.0.0.1,ip:[::1],DNS:%s", + ip, hostName), // "-genkeypair", // "-keyalg", "RSA", // "-keypass", keyPassword, // @@ -260,12 +271,12 @@ public ServletContextHandler authBasic(ServletContextHandler ctx, } static class TestMappedLoginService extends AbstractLoginService { - private String role; + private RolePrincipal role; protected final Map users = new ConcurrentHashMap<>(); TestMappedLoginService(String role) { - this.role = role; + this.role = new RolePrincipal(role); } @Override @@ -277,16 +288,16 @@ protected void doStart() throws Exception { } @Override - protected String[] loadRoleInfo(UserPrincipal user) { - if (users.get(user.getName()) == null) { - return null; - } - return new String[] { role }; + protected UserPrincipal loadUserInfo(String user) { + return users.get(user); } @Override - protected UserPrincipal loadUserInfo(String user) { - return users.get(user); + protected List loadRoleInfo(UserPrincipal user) { + if (users.get(user.getName()) == null) { + return null; + } + return Collections.singletonList(role); } } diff --git a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF index 95ac89b0b..7a5227022 100644 --- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF @@ -7,27 +7,25 @@ Bundle-Version: 6.0.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-11 -Import-Package: javax.servlet;version="[3.1.0,4.0.0)", - javax.servlet.http;version="[3.1.0,4.0.0)", +Import-Package: javax.servlet;version="[3.1.0,5.0.0)", + javax.servlet.http;version="[3.1.0,5.0.0)", org.apache.http;version="[4.4.0,5.0.0)", org.apache.http.client;version="[4.4.0,5.0.0)", org.apache.http.client.methods;version="[4.4.0,5.0.0)", org.apache.http.entity;version="[4.4.0,5.0.0)", org.apache.http.impl.client;version="[4.4.0,5.0.0)", - org.eclipse.jetty.continuation;version="[9.4.5,10.0.0)", - org.eclipse.jetty.http;version="[9.4.5,10.0.0)", - org.eclipse.jetty.io;version="[9.4.5,10.0.0)", - org.eclipse.jetty.security;version="[9.4.5,10.0.0)", - org.eclipse.jetty.security.authentication;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server.handler;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server.nio;version="[9.4.5,10.0.0)", - org.eclipse.jetty.servlet;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.component;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.log;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.security;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.thread;version="[9.4.5,10.0.0)", + org.eclipse.jetty.http;version="[10.0.0,11.0.0)", + org.eclipse.jetty.io;version="[10.0.0,11.0.0)", + org.eclipse.jetty.security;version="[10.0.0,11.0.0)", + org.eclipse.jetty.security.authentication;version="[10.0.0,11.0.0)", + org.eclipse.jetty.server;version="[10.0.0,11.0.0)", + org.eclipse.jetty.server.handler;version="[10.0.0,11.0.0)", + org.eclipse.jetty.servlet;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.component;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.thread;version="[10.0.0,11.0.0)", org.eclipse.jgit.api;version="[6.0.0,6.1.0)", org.eclipse.jgit.api.errors;version="[6.0.0,6.1.0)", org.eclipse.jgit.internal.storage.file;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml index 2c1b13429..fea9da52f 100644 --- a/org.eclipse.jgit.lfs.server.test/pom.xml +++ b/org.eclipse.jgit.lfs.server.test/pom.xml @@ -27,6 +27,10 @@ Tests for the LFS server. + + true + + junit diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF index c5d844426..e1f026acf 100644 --- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF @@ -20,9 +20,9 @@ Export-Package: org.eclipse.jgit.lfs.server;version="6.0.0"; org.eclipse.jgit.lfs.lib" Bundle-RequiredExecutionEnvironment: JavaSE-11 Import-Package: com.google.gson;version="[2.8.0,3.0.0)", - javax.servlet;version="[3.1.0,4.0.0)", - javax.servlet.annotation;version="[3.1.0,4.0.0)", - javax.servlet.http;version="[3.1.0,4.0.0)", + javax.servlet;version="[3.1.0,5.0.0)", + javax.servlet.annotation;version="[3.1.0,5.0.0)", + javax.servlet.http;version="[3.1.0,5.0.0)", org.apache.http;version="[4.3.0,5.0.0)", org.eclipse.jgit.annotations;version="[6.0.0,6.1.0)", org.eclipse.jgit.internal;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml index 262258c2d..7c1ab5846 100644 --- a/org.eclipse.jgit.lfs.test/pom.xml +++ b/org.eclipse.jgit.lfs.test/pom.xml @@ -27,6 +27,10 @@ Tests for the Large File Extension (LFS). + + true + + junit diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml index a15d0fd76..af9523fd4 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml @@ -75,10 +75,52 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 06090e674..737cadaf9 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,28 +1,26 @@ - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -37,8 +35,6 @@ - - @@ -93,7 +89,7 @@ - + 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 16527013b..cd364d356 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-9.4.x.tpd" -include "orbit/S20211108222137.tpd" +include "projects/jetty-10.0.x.tpd" +include "orbit/R20211122181901-2021-12.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 1d6792229..55cadffa8 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,28 +1,26 @@ - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -37,8 +35,6 @@ - - @@ -93,7 +89,7 @@ - + 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 e732ad6d1..27f3471c1 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-9.4.x.tpd" -include "orbit/S20211108222137.tpd" +include "projects/jetty-10.0.x.tpd" +include "orbit/R20211122181901-2021-12.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 8b96f5269..43fe4c841 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,28 +1,26 @@ - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -37,8 +35,6 @@ - - @@ -93,7 +89,7 @@ - + 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 0e77c8872..419999652 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-9.4.x.tpd" -include "orbit/S20211108222137.tpd" +include "projects/jetty-10.0.x.tpd" +include "orbit/R20211122181901-2021-12.tpd" location "https://download.eclipse.org/staging/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 a3aca8d79..aefa34122 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,28 +1,26 @@ - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -37,8 +35,6 @@ - - @@ -93,7 +89,7 @@ - + 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 081864849..37123e5fa 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-9.4.x.tpd" -include "orbit/S20211108222137.tpd" +include "projects/jetty-10.0.x.tpd" +include "orbit/R20211122181901-2021-12.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 5f4498723..1b6cf26a5 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,28 +1,26 @@ - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -37,8 +35,6 @@ - - @@ -93,7 +89,7 @@ - + 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 53848b269..2949e50a2 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-9.4.x.tpd" -include "orbit/S20211108222137.tpd" +include "projects/jetty-10.0.x.tpd" +include "orbit/R20211122181901-2021-12.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 new file mode 100644 index 000000000..7fd003277 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 000000000..db3db2877 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd @@ -0,0 +1,8 @@ +target "jgit-4.22" with source configurePhase + +include "projects/jetty-10.0.x.tpd" +include "orbit/R20211122181901-2021-12.tpd" + +location "https://download.eclipse.org/releases/2021-12/" { + org.eclipse.osgi lazy +} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20211108222137.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20211122181901-2021-12.tpd similarity index 95% rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20211108222137.tpd rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20211122181901-2021-12.tpd index 0f0701099..cd1d1c08f 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20211108222137.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20211122181901-2021-12.tpd @@ -1,7 +1,7 @@ -target "S20211108222137" with source configurePhase +target "R20211122181901-2021-12" with source configurePhase // see https://download.eclipse.org/tools/orbit/downloads/ -location "https://download.eclipse.org/tools/orbit/downloads/drops/S20211108222137/repository" { +location "https://download.eclipse.org/tools/orbit/downloads/drops/R20211122181901/repository" { com.google.gson [2.8.8.v20211029-0838,2.8.8.v20211029-0838] com.google.gson.source [2.8.8.v20211029-0838,2.8.8.v20211029-0838] com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902] @@ -14,8 +14,6 @@ location "https://download.eclipse.org/tools/orbit/downloads/drops/S202111082221 com.sun.jna.platform.source [5.8.0.v20210406-1004,5.8.0.v20210406-1004] javaewah [1.1.13.v20211029-0839,1.1.13.v20211029-0839] javaewah.source [1.1.13.v20211029-0839,1.1.13.v20211029-0839] - javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800] - javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800] net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410] net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534] net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534] diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd new file mode 100644 index 000000000..6c3ee1833 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd @@ -0,0 +1,20 @@ +target "jetty-10.0.x" with source configurePhase + +location jetty-10.0.x "https://download.eclipse.org/eclipse/jetty/10.0.6/" { + jakarta.servlet-api [4.0.0, 5.0.0) + jakarta.servlet-api.source [4.0.0, 5.0.0) + org.eclipse.jetty.http [10.0.6,10.0.6] + org.eclipse.jetty.http.source [10.0.6,10.0.6] + org.eclipse.jetty.io [10.0.6,10.0.6] + org.eclipse.jetty.io.source [10.0.6,10.0.6] + org.eclipse.jetty.security [10.0.6,10.0.6] + org.eclipse.jetty.security.source [10.0.6,10.0.6] + org.eclipse.jetty.server [10.0.6,10.0.6] + org.eclipse.jetty.server.source [10.0.6,10.0.6] + org.eclipse.jetty.servlet [10.0.6,10.0.6] + org.eclipse.jetty.servlet.source [10.0.6,10.0.6] + org.eclipse.jetty.util [10.0.6,10.0.6] + org.eclipse.jetty.util.source [10.0.6,10.0.6] + org.eclipse.jetty.util.ajax [10.0.6,10.0.6] + org.eclipse.jetty.util.ajax.source [10.0.6,10.0.6] +} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd deleted file mode 100644 index 8a143ce24..000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd +++ /dev/null @@ -1,22 +0,0 @@ -target "jetty-9.4.x" with source configurePhase - -location jetty-9.4.x "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.44.v20210927/" { - org.eclipse.jetty.client [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.client.source [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.continuation [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.continuation.source [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.http [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.http.source [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.io [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.io.source [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.security [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.security.source [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.server [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.server.source [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.servlet [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.servlet.source [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.util [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.util.source [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.util.ajax [9.4.44.v20210927,9.4.44.v20210927] - org.eclipse.jetty.util.ajax.source [9.4.44.v20210927,9.4.44.v20210927] -} diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml index 85f96c597..83d536936 100644 --- a/org.eclipse.jgit.pgm.test/pom.xml +++ b/org.eclipse.jgit.pgm.test/pom.xml @@ -27,6 +27,10 @@ Tests for command line client tools built on top of JGit. + + true + + junit diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index 89ad6d1f3..f46a3fae6 100644 --- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF @@ -7,13 +7,13 @@ Bundle-Version: 6.0.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-11 -Import-Package: javax.servlet;version="[3.1.0,4.0.0)", +Import-Package: javax.servlet;version="[3.1.0,5.0.0)", org.apache.commons.logging;version="[1.2,2.0)", - org.eclipse.jetty.server;version="[9.4.5,10.0.0)", - org.eclipse.jetty.server.handler;version="[9.4.5,10.0.0)", - org.eclipse.jetty.servlet;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util;version="[9.4.5,10.0.0)", - org.eclipse.jetty.util.component;version="[9.4.5,10.0.0)", + org.eclipse.jetty.server;version="[10.0.0,11.0.0)", + org.eclipse.jetty.server.handler;version="[10.0.0,11.0.0)", + org.eclipse.jetty.servlet;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util;version="[10.0.0,11.0.0)", + org.eclipse.jetty.util.component;version="[10.0.0,11.0.0)", org.eclipse.jgit.api;version="[6.0.0,6.1.0)", org.eclipse.jgit.api.errors;version="[6.0.0,6.1.0)", org.eclipse.jgit.archive;version="[6.0.0,6.1.0)", diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java index f7b37d781..e2dbb4c46 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java @@ -71,9 +71,9 @@ public class JGitClientSession extends ClientSessionImpl { /** * Default setting for the maximum number of bytes to read in the initial - * protocol version exchange. 64kb is what OpenSSH < 8.0 read; OpenSSH 8.0 - * changed it to 8Mb, but that seems excessive for the purpose stated in RFC - * 4253. The Apache MINA sshd default in + * protocol version exchange. 64kb is what OpenSSH < 8.0 read; OpenSSH + * 8.0 changed it to 8Mb, but that seems excessive for the purpose stated in + * RFC 4253. The Apache MINA sshd default in * {@link org.apache.sshd.core.CoreModuleProperties#MAX_IDENTIFICATION_SIZE} * is 16kb. */ diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/AbstractClientProxyConnector.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/AbstractClientProxyConnector.java index ae2b2b6ac..a8e33af35 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/AbstractClientProxyConnector.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/AbstractClientProxyConnector.java @@ -105,7 +105,7 @@ protected void init(ClientSession session) { /** * Obtains the timeout for the whole rest of the proxy connection protocol. * - * @return the timeout in milliseconds, always > 0L + * @return the timeout in milliseconds, always > 0L */ protected long getTimeout() { long last = lastProxyOperationTime; diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/KeyPasswordProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/KeyPasswordProvider.java index acc11cefb..ed9fe37d5 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/KeyPasswordProvider.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/KeyPasswordProvider.java @@ -31,7 +31,7 @@ public interface KeyPasswordProvider { * identifying the key resource that is being attempted to be * loaded * @param attempt - * the number of previous attempts to get a passphrase; >= 0 + * the number of previous attempts to get a passphrase; >= 0 * @return the passphrase * @throws IOException * if no password can be obtained @@ -44,7 +44,7 @@ public interface KeyPasswordProvider { * * @param maxNumberOfAttempts * number of times to ask for a passphrase; - * {@link IllegalArgumentException} may be thrown if <= 0 + * {@link IllegalArgumentException} may be thrown if <= 0 */ void setAttempts(int maxNumberOfAttempts); @@ -53,7 +53,7 @@ public interface KeyPasswordProvider { * attempted for one identity resource through this provider. The default * return 1. * - * @return the number of times to ask for a passphrase; should be >= 1. + * @return the number of times to ask for a passphrase; should be >= 1. */ default int getAttempts() { return 1; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheTest.java index 549e1f469..4f1314057 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheTest.java @@ -10,6 +10,7 @@ package org.eclipse.jgit.internal.storage.dfs; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -20,11 +21,10 @@ import java.util.List; import java.util.Map; import java.util.stream.LongStream; - import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; + import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRng; @@ -42,10 +42,12 @@ public class DfsBlockCacheTest { public TestName testName = new TestName(); private TestRng rng; private DfsBlockCache cache; + private ExecutorService pool; @Before public void setUp() { rng = new TestRng(testName.getMethodName()); + pool = Executors.newFixedThreadPool(10); resetCache(); } @@ -152,49 +154,169 @@ public void hasCacheHotMap() throws Exception { @SuppressWarnings("resource") @Test - public void noConcurrencySerializedReads() throws Exception { - DfsRepositoryDescription repo = new DfsRepositoryDescription("test"); - InMemoryRepository r1 = new InMemoryRepository(repo); - TestRepository repository = new TestRepository<>( - r1); - RevCommit commit = repository.branch("/refs/ref1").commit() - .add("blob1", "blob1").create(); - repository.branch("/refs/ref2").commit().add("blob2", "blob2") - .parent(commit).create(); - - new DfsGarbageCollector(r1).pack(null); + public void noConcurrencySerializedReads_oneRepo() throws Exception { + InMemoryRepository r1 = createRepoWithBitmap("test"); // Reset cache with concurrency Level at 1 i.e. no concurrency. - DfsBlockCache.reconfigure(new DfsBlockCacheConfig().setBlockSize(512) - .setBlockLimit(1 << 20).setConcurrencyLevel(1)); - cache = DfsBlockCache.getInstance(); + resetCache(1); DfsReader reader = (DfsReader) r1.newObjectReader(); - ExecutorService pool = Executors.newFixedThreadPool(10); for (DfsPackFile pack : r1.getObjectDatabase().getPacks()) { // Only load non-garbage pack with bitmap. if (pack.isGarbage()) { continue; } - asyncRun(pool, () -> pack.getBitmapIndex(reader)); - asyncRun(pool, () -> pack.getPackIndex(reader)); - asyncRun(pool, () -> pack.getBitmapIndex(reader)); + asyncRun(() -> pack.getBitmapIndex(reader)); + asyncRun(() -> pack.getPackIndex(reader)); + asyncRun(() -> pack.getBitmapIndex(reader)); } + waitForExecutorPoolTermination(); - pool.shutdown(); - pool.awaitTermination(500, TimeUnit.MILLISECONDS); - assertTrue("Threads did not complete, likely due to a deadlock.", - pool.isTerminated()); assertEquals(1, cache.getMissCount()[PackExt.BITMAP_INDEX.ordinal()]); assertEquals(1, cache.getMissCount()[PackExt.INDEX.ordinal()]); + // Reverse index has no pack extension, it defaults to 0. + assertEquals(1, cache.getMissCount()[0]); + } + + @SuppressWarnings("resource") + @Test + public void noConcurrencySerializedReads_twoRepos() throws Exception { + InMemoryRepository r1 = createRepoWithBitmap("test1"); + InMemoryRepository r2 = createRepoWithBitmap("test2"); + resetCache(1); + + DfsReader reader = (DfsReader) r1.newObjectReader(); + DfsPackFile[] r1Packs = r1.getObjectDatabase().getPacks(); + DfsPackFile[] r2Packs = r2.getObjectDatabase().getPacks(); + // Safety check that both repos have the same number of packs. + assertEquals(r1Packs.length, r2Packs.length); + + for (int i = 0; i < r1.getObjectDatabase().getPacks().length; ++i) { + DfsPackFile pack1 = r1Packs[i]; + DfsPackFile pack2 = r2Packs[i]; + if (pack1.isGarbage() || pack2.isGarbage()) { + continue; + } + asyncRun(() -> pack1.getBitmapIndex(reader)); + asyncRun(() -> pack2.getBitmapIndex(reader)); + } + + waitForExecutorPoolTermination(); + assertEquals(2, cache.getMissCount()[PackExt.BITMAP_INDEX.ordinal()]); + assertEquals(2, cache.getMissCount()[PackExt.INDEX.ordinal()]); + assertEquals(2, cache.getMissCount()[0]); + } + + @SuppressWarnings("resource") + @Test + public void lowConcurrencyParallelReads_twoRepos() throws Exception { + InMemoryRepository r1 = createRepoWithBitmap("test1"); + InMemoryRepository r2 = createRepoWithBitmap("test2"); + resetCache(2); + + DfsReader reader = (DfsReader) r1.newObjectReader(); + DfsPackFile[] r1Packs = r1.getObjectDatabase().getPacks(); + DfsPackFile[] r2Packs = r2.getObjectDatabase().getPacks(); + // Safety check that both repos have the same number of packs. + assertEquals(r1Packs.length, r2Packs.length); + + for (int i = 0; i < r1.getObjectDatabase().getPacks().length; ++i) { + DfsPackFile pack1 = r1Packs[i]; + DfsPackFile pack2 = r2Packs[i]; + if (pack1.isGarbage() || pack2.isGarbage()) { + continue; + } + asyncRun(() -> pack1.getBitmapIndex(reader)); + asyncRun(() -> pack2.getBitmapIndex(reader)); + } + + waitForExecutorPoolTermination(); + assertEquals(2, cache.getMissCount()[PackExt.BITMAP_INDEX.ordinal()]); + assertEquals(2, cache.getMissCount()[PackExt.INDEX.ordinal()]); + assertEquals(2, cache.getMissCount()[0]); + } + + @SuppressWarnings("resource") + @Test + public void lowConcurrencyParallelReads_twoReposAndIndex() + throws Exception { + InMemoryRepository r1 = createRepoWithBitmap("test1"); + InMemoryRepository r2 = createRepoWithBitmap("test2"); + resetCache(2); + + DfsReader reader = (DfsReader) r1.newObjectReader(); + DfsPackFile[] r1Packs = r1.getObjectDatabase().getPacks(); + DfsPackFile[] r2Packs = r2.getObjectDatabase().getPacks(); + // Safety check that both repos have the same number of packs. + assertEquals(r1Packs.length, r2Packs.length); + + for (int i = 0; i < r1.getObjectDatabase().getPacks().length; ++i) { + DfsPackFile pack1 = r1Packs[i]; + DfsPackFile pack2 = r2Packs[i]; + if (pack1.isGarbage() || pack2.isGarbage()) { + continue; + } + asyncRun(() -> pack1.getBitmapIndex(reader)); + asyncRun(() -> pack1.getPackIndex(reader)); + asyncRun(() -> pack2.getBitmapIndex(reader)); + } + waitForExecutorPoolTermination(); + + assertEquals(2, cache.getMissCount()[PackExt.BITMAP_INDEX.ordinal()]); + // Index is loaded once for each repo. + assertEquals(2, cache.getMissCount()[PackExt.INDEX.ordinal()]); + assertEquals(2, cache.getMissCount()[0]); + } + + @SuppressWarnings("resource") + @Test + public void highConcurrencyParallelReads_oneRepo() throws Exception { + InMemoryRepository r1 = createRepoWithBitmap("test"); + resetCache(); + + DfsReader reader = (DfsReader) r1.newObjectReader(); + for (DfsPackFile pack : r1.getObjectDatabase().getPacks()) { + // Only load non-garbage pack with bitmap. + if (pack.isGarbage()) { + continue; + } + asyncRun(() -> pack.getBitmapIndex(reader)); + asyncRun(() -> pack.getPackIndex(reader)); + asyncRun(() -> pack.getBitmapIndex(reader)); + } + waitForExecutorPoolTermination(); + + assertEquals(1, cache.getMissCount()[PackExt.BITMAP_INDEX.ordinal()]); + assertEquals(1, cache.getMissCount()[PackExt.INDEX.ordinal()]); + assertEquals(1, cache.getMissCount()[0]); } private void resetCache() { + resetCache(32); + } + + private void resetCache(int concurrencyLevel) { DfsBlockCache.reconfigure(new DfsBlockCacheConfig().setBlockSize(512) - .setBlockLimit(1 << 20)); + .setConcurrencyLevel(concurrencyLevel).setBlockLimit(1 << 20)); cache = DfsBlockCache.getInstance(); } - private void asyncRun(ExecutorService pool, Callable call) { + private InMemoryRepository createRepoWithBitmap(String repoName) + throws Exception { + DfsRepositoryDescription repoDesc = new DfsRepositoryDescription( + repoName); + InMemoryRepository repo = new InMemoryRepository(repoDesc); + try (TestRepository repository = new TestRepository<>( + repo)) { + RevCommit commit = repository.branch("/refs/ref1" + repoName) + .commit().add("blob1", "blob1" + repoName).create(); + repository.branch("/refs/ref2" + repoName).commit() + .add("blob2", "blob2" + repoName).parent(commit).create(); + } + new DfsGarbageCollector(repo).pack(null); + return repo; + } + + private void asyncRun(Callable call) { pool.execute(() -> { try { call.call(); @@ -203,4 +325,11 @@ private void asyncRun(ExecutorService pool, Callable call) { } }); } + + private void waitForExecutorPoolTermination() throws Exception { + pool.shutdown(); + pool.awaitTermination(500, MILLISECONDS); + assertTrue("Threads did not complete, likely due to a deadlock.", + pool.isTerminated()); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java index fe3c1db50..9ee54d5b6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.junit.MockSystemReader; import org.eclipse.jgit.merge.MergeConfig; import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.SystemReader; @@ -1471,14 +1472,17 @@ public void testCommitTemplateEmptyConfig() // no values defined nowhere Config config = new Config(null); assertNull(config.get(CommitConfig.KEY).getCommitTemplatePath()); - assertNull(config.get(CommitConfig.KEY).getCommitTemplateContent()); + assertNull(config.get(CommitConfig.KEY) + .getCommitTemplateContent(null)); } @Test public void testCommitTemplateConfig() throws ConfigInvalidException, IOException { + File workTree = tmp.newFolder("dummy-worktree"); File tempFile = tmp.newFile("testCommitTemplate-"); + Repository repo = FileRepositoryBuilder.create(workTree); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); String expectedTemplatePath = tempFile.getPath(); @@ -1492,7 +1496,32 @@ public void testCommitTemplateConfig() .getCommitEncoding(); assertEquals(expectedTemplatePath, templatePath); assertEquals(templateContent, - config.get(CommitConfig.KEY).getCommitTemplateContent()); + config.get(CommitConfig.KEY).getCommitTemplateContent(repo)); + assertNull("no commitEncoding has been set so it must be null", + commitEncoding); + } + + @Test + public void testCommitTemplateConfigRelativePath() + throws ConfigInvalidException, IOException { + + File workTree = tmp.newFolder("dummy-worktree"); + File tempFile = tmp.newFile("testCommitTemplate-"); + String templateContent = "content of the template"; + JGitTestUtil.write(tempFile, templateContent); + String expectedTemplatePath = "../" + tempFile.getName(); + + Config config = parse( + "[commit]\n\ttemplate = " + expectedTemplatePath + "\n"); + + String templatePath = config.get(CommitConfig.KEY) + .getCommitTemplatePath(); + String commitEncoding = config.get(CommitConfig.KEY) + .getCommitEncoding(); + assertEquals(expectedTemplatePath, templatePath); + assertEquals(templateContent, config.get(CommitConfig.KEY) + .getCommitTemplateContent( + new RepositoryBuilder().setWorkTree(workTree).build())); assertNull("no commitEncoding has been set so it must be null", commitEncoding); } @@ -1501,6 +1530,8 @@ public void testCommitTemplateConfig() public void testCommitTemplateEncoding() throws ConfigInvalidException, IOException { Config config = new Config(null); + File workTree = tmp.newFolder("dummy-worktree"); + Repository repo = FileRepositoryBuilder.create(workTree); File tempFile = tmp.newFile("testCommitTemplate-"); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); @@ -1508,7 +1539,7 @@ public void testCommitTemplateEncoding() config = parse("[i18n]\n\tcommitEncoding = utf-8\n" + "[commit]\n\ttemplate = " + expectedTemplatePath + "\n"); assertEquals(templateContent, - config.get(CommitConfig.KEY).getCommitTemplateContent()); + config.get(CommitConfig.KEY).getCommitTemplateContent(repo)); String commitEncoding = config.get(CommitConfig.KEY) .getCommitEncoding(); assertEquals("commitEncoding has been set to utf-8 it must be utf-8", @@ -1520,6 +1551,8 @@ public void testCommitTemplatePathInHomeDirecory() throws ConfigInvalidException, IOException { Config config = new Config(null); File tempFile = tmp.newFile("testCommitTemplate-"); + File workTree = tmp.newFolder("dummy-worktree"); + Repository repo = FileRepositoryBuilder.create(workTree); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); // proper evaluation of the ~/ directory @@ -1535,35 +1568,39 @@ public void testCommitTemplatePathInHomeDirecory() .getCommitTemplatePath(); assertEquals(expectedTemplatePath, templatePath); assertEquals(templateContent, - config.get(CommitConfig.KEY).getCommitTemplateContent()); + config.get(CommitConfig.KEY).getCommitTemplateContent(repo)); } @Test(expected = ConfigInvalidException.class) public void testCommitTemplateWithInvalidEncoding() throws ConfigInvalidException, IOException { Config config = new Config(null); + File workTree = tmp.newFolder("dummy-worktree"); File tempFile = tmp.newFile("testCommitTemplate-"); + Repository repo = FileRepositoryBuilder.create(workTree); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); config = parse("[i18n]\n\tcommitEncoding = invalidEcoding\n" + "[commit]\n\ttemplate = " + tempFile.getPath() + "\n"); - config.get(CommitConfig.KEY).getCommitTemplateContent(); + config.get(CommitConfig.KEY).getCommitTemplateContent(repo); } @Test(expected = FileNotFoundException.class) public void testCommitTemplateWithInvalidPath() throws ConfigInvalidException, IOException { Config config = new Config(null); + File workTree = tmp.newFolder("dummy-worktree"); File tempFile = tmp.newFile("testCommitTemplate-"); + Repository repo = FileRepositoryBuilder.create(workTree); String templateContent = "content of the template"; JGitTestUtil.write(tempFile, templateContent); // commit message encoding - String expectedTemplatePath = "nonExistingTemplate"; + String expectedTemplatePath = "/nonExistingTemplate"; config = parse("[commit]\n\ttemplate = " + expectedTemplatePath + "\n"); String templatePath = config.get(CommitConfig.KEY) .getCommitTemplatePath(); assertEquals(expectedTemplatePath, templatePath); - config.get(CommitConfig.KEY).getCommitTemplateContent(); + config.get(CommitConfig.KEY).getCommitTemplateContent(repo); } private static void assertValueRoundTrip(String value) 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 f4bbb4c9f..1c5a52180 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 @@ -34,7 +34,6 @@ import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector; import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.internal.storage.pack.CachedPack; import org.eclipse.jgit.internal.storage.pack.CachedPackUriProvider; import org.eclipse.jgit.junit.TestRepository; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java index b69bb8f3e..ca5370e91 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java @@ -71,12 +71,12 @@ class Candidate { /** * Score assigned to the rename to this candidate. *

- * Consider the history "A<-B<-C". If the result file S in C was renamed to - * R in B, the rename score for this rename will be held in this field by - * the candidate object for B. By storing the score with B, the application - * can see what the rename score was as it makes the transition from C/S to - * B/R. This may seem backwards since it was C that performed the rename, - * but the application doesn't learn about path R until B. + * Consider the history "A<-B<-C". If the result file S in C was + * renamed to R in B, the rename score for this rename will be held in this + * field by the candidate object for B. By storing the score with B, the + * application can see what the rename score was as it makes the transition + * from C/S to B/R. This may seem backwards since it was C that performed + * the rename, but the application doesn't learn about path R until B. */ int renameScore; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java index e226dbf3c..2236eecbf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java @@ -27,7 +27,7 @@ class Region { /** First position in the {@link Candidate} that owns this Region. */ int sourceStart; - /** Length of the region, always >= 1. */ + /** Length of the region, always >= 1. */ int length; Region(int rs, int ss, int len) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java index ec21954aa..49da95c9a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java @@ -29,12 +29,12 @@ import java.util.Collections; import java.util.List; +import org.eclipse.jgit.api.errors.CanceledException; import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm; import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.errors.AmbiguousObjectException; import org.eclipse.jgit.errors.BinaryBlobException; -import org.eclipse.jgit.errors.CancelledException; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -578,7 +578,7 @@ private List detectRenames(List files) renameDetector.addAll(files); try { return renameDetector.compute(reader, progressMonitor); - } catch (CancelledException e) { + } catch (CanceledException e) { // TODO: consider propagating once bug 536323 is tackled // (making DiffEntry.scan() and DiffFormatter.scan() and // format() cancellable). diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java index 225921ecc..c33f53add 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java @@ -23,9 +23,9 @@ import java.util.HashMap; import java.util.List; +import org.eclipse.jgit.api.errors.CanceledException; import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.diff.SimilarityIndex.TableFullException; -import org.eclipse.jgit.errors.CancelledException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.jgit.lib.FileMode; @@ -336,6 +336,7 @@ public void add(DiffEntry entry) { * Detect renames in the current file set. *

* This convenience function runs without a progress monitor. + *

* * @return an unmodifiable list of {@link org.eclipse.jgit.diff.DiffEntry}s * representing all files that have been changed. @@ -343,7 +344,12 @@ public void add(DiffEntry entry) { * file contents cannot be read from the repository. */ public List compute() throws IOException { - return compute(NullProgressMonitor.INSTANCE); + try { + return compute(NullProgressMonitor.INSTANCE); + } catch (CanceledException e) { + // Won't happen with a NullProgressMonitor + return Collections.emptyList(); + } } /** @@ -355,13 +361,11 @@ public List compute() throws IOException { * representing all files that have been changed. * @throws java.io.IOException * file contents cannot be read from the repository. - * @throws CancelledException + * @throws CanceledException * if rename detection was cancelled */ - // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major - // version public List compute(ProgressMonitor pm) - throws IOException, CancelledException { + throws IOException, CanceledException { if (!done) { try { return compute(objectReader, pm); @@ -383,13 +387,11 @@ public List compute(ProgressMonitor pm) * representing all files that have been changed. * @throws java.io.IOException * file contents cannot be read from the repository. - * @throws CancelledException + * @throws CanceledException * if rename detection was cancelled */ - // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major - // version public List compute(ObjectReader reader, ProgressMonitor pm) - throws IOException, CancelledException { + throws IOException, CanceledException { final ContentSource cs = ContentSource.create(reader); return compute(new ContentSource.Pair(cs, cs), pm); } @@ -405,13 +407,11 @@ public List compute(ObjectReader reader, ProgressMonitor pm) * representing all files that have been changed. * @throws java.io.IOException * file contents cannot be read from the repository. - * @throws CancelledException + * @throws CanceledException * if rename detection was cancelled */ - // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major - // version public List compute(ContentSource.Pair reader, ProgressMonitor pm) - throws IOException, CancelledException { + throws IOException, CanceledException { if (!done) { done = true; @@ -451,15 +451,15 @@ public void reset() { done = false; } - private void advanceOrCancel(ProgressMonitor pm) throws CancelledException { + private void advanceOrCancel(ProgressMonitor pm) throws CanceledException { if (pm.isCancelled()) { - throw new CancelledException(JGitText.get().renameCancelled); + throw new CanceledException(JGitText.get().renameCancelled); } pm.update(1); } private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm) - throws IOException, CancelledException { + throws IOException, CanceledException { ArrayList newEntries = new ArrayList<>(entries.size()); pm.beginTask(JGitText.get().renamesBreakingModifies, entries.size()); @@ -486,7 +486,7 @@ private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm) entries = newEntries; } - private void rejoinModifies(ProgressMonitor pm) throws CancelledException { + private void rejoinModifies(ProgressMonitor pm) throws CanceledException { HashMap nameMap = new HashMap<>(); ArrayList newAdded = new ArrayList<>(added.size()); @@ -541,7 +541,7 @@ private int calculateModifyScore(ContentSource.Pair reader, DiffEntry d) private void findContentRenames(ContentSource.Pair reader, ProgressMonitor pm) - throws IOException, CancelledException { + throws IOException, CanceledException { int cnt = Math.max(added.size(), deleted.size()); if (getRenameLimit() == 0 || cnt <= getRenameLimit()) { SimilarityRenameDetector d; @@ -562,7 +562,7 @@ private void findContentRenames(ContentSource.Pair reader, @SuppressWarnings("unchecked") private void findExactRenames(ProgressMonitor pm) - throws CancelledException { + throws CanceledException { pm.beginTask(JGitText.get().renamesFindingExact, // added.size() + added.size() + deleted.size() + added.size() * deleted.size()); @@ -651,7 +651,7 @@ private void findExactRenames(ProgressMonitor pm) matrix[mNext] = SimilarityRenameDetector.encode(score, delIdx, addIdx); mNext++; if (pm.isCancelled()) { - throw new CancelledException( + throw new CanceledException( JGitText.get().renameCancelled); } } @@ -744,7 +744,7 @@ private static DiffEntry bestPathMatch(DiffEntry src, List list) { @SuppressWarnings("unchecked") private HashMap populateMap( List diffEntries, ProgressMonitor pm) - throws CancelledException { + throws CanceledException { HashMap map = new HashMap<>(); for (DiffEntry de : diffEntries) { Object old = map.put(id(de), de); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java index 5871b4aee..9ac94895b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java @@ -20,9 +20,9 @@ import java.util.BitSet; import java.util.List; +import org.eclipse.jgit.api.errors.CanceledException; import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.diff.SimilarityIndex.TableFullException; -import org.eclipse.jgit.errors.CancelledException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.NullProgressMonitor; @@ -115,7 +115,7 @@ void setSkipBinaryFiles(boolean value) { skipBinaryFiles = value; } - void compute(ProgressMonitor pm) throws IOException, CancelledException { + void compute(ProgressMonitor pm) throws IOException, CanceledException { if (pm == null) pm = NullProgressMonitor.INSTANCE; @@ -130,9 +130,7 @@ void compute(ProgressMonitor pm) throws IOException, CancelledException { // for (--mNext; mNext >= 0; mNext--) { if (pm.isCancelled()) { - // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException - // in next major version - throw new CancelledException(JGitText.get().renameCancelled); + throw new CanceledException(JGitText.get().renameCancelled); } long ent = matrix[mNext]; int sIdx = srcFile(ent); @@ -202,7 +200,7 @@ private static List compactDstList(List in) { } private int buildMatrix(ProgressMonitor pm) - throws IOException, CancelledException { + throws IOException, CanceledException { // Allocate for the worst-case scenario where every pair has a // score that we need to consider. We might not need that many. // @@ -228,10 +226,7 @@ private int buildMatrix(ProgressMonitor pm) for (int dstIdx = 0; dstIdx < dsts.size(); dstIdx++) { if (pm.isCancelled()) { - // TODO(ms): use - // org.eclipse.jgit.api.errors.CanceledException in next - // major version - throw new CancelledException( + throw new CanceledException( JGitText.get().renameCancelled); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java index 07162db4c..e0c1e9391 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java @@ -280,12 +280,12 @@ public String getPathString() { * number of bytes of cache[cacheIdx].path that * matches this tree's path. The value at array position * cache[cacheIdx].path[pathOff-1] is always '/' if - * pathOff is > 0. + * pathOff is > 0. * @param ow * the writer to use when serializing to the store. * @return identity of this tree. * @throws UnmergedPathException - * one or more paths contain higher-order stages (stage > 0), + * one or more paths contain higher-order stages (stage > 0), * which cannot be stored in a tree object. * @throws IOException * an unexpected error occurred writing to the object store. @@ -401,7 +401,7 @@ final boolean contains(byte[] a, int aOff, int aLen) { * number of bytes of cache[cacheIdx].path that * matches this tree's path. The value at array position * cache[cacheIdx].path[pathOff-1] is always '/' if - * pathOff is > 0. + * pathOff is > 0. */ void validate(final DirCacheEntry[] cache, final int cCnt, int cIdx, final int pathOff) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/StoredObjectRepresentationNotAvailableException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/StoredObjectRepresentationNotAvailableException.java index 0708123e9..de210b01c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/StoredObjectRepresentationNotAvailableException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/StoredObjectRepresentationNotAvailableException.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, Google Inc. and others + * Copyright (C) 2010, 2021 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 @@ -7,29 +7,23 @@ * * SPDX-License-Identifier: BSD-3-Clause */ - package org.eclipse.jgit.errors; -import org.eclipse.jgit.internal.storage.pack.ObjectToPack; - /** * A previously selected representation is no longer available. */ -public class StoredObjectRepresentationNotAvailableException extends Exception { //TODO remove unused ObjectToPack in 5.0 +public class StoredObjectRepresentationNotAvailableException extends Exception { + private static final long serialVersionUID = 1L; /** - * Construct an error for an object. + * Creates a new instance. * - * @param otp - * the object whose current representation is no longer present. * @param cause - * cause - * @since 4.10 + * {@link Throwable} that caused this exception + * @since 6.0 */ - public StoredObjectRepresentationNotAvailableException(ObjectToPack otp, - Throwable cause) { + public StoredObjectRepresentationNotAvailableException(Throwable cause) { super(cause); - // Do nothing. } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java index 095927f3c..e0a822479 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -578,10 +578,10 @@ public RevCommit call() throws GitAPIException { DirCache index = DirCache.newInCore(); ObjectInserter inserter = repo.newObjectInserter(); + try (RevWalk rw = new RevWalk(repo)) { prepareIndex(renamedProjects, index, inserter); ObjectId treeId = index.writeTree(inserter); - long prevDelay = 0; for (int i = 0; i < LOCK_FAILURE_MAX_RETRIES - 1; i++) { try { @@ -597,7 +597,7 @@ public RevCommit call() throws GitAPIException { } // In the last try, just propagate the exceptions return commitTreeOnCurrentTip(inserter, rw, treeId); - } catch (GitAPIException | IOException | InterruptedException e) { + } catch (IOException | InterruptedException e) { throw new ManifestErrorException(e); } } @@ -609,12 +609,11 @@ public RevCommit call() throws GitAPIException { } return git.commit().setMessage(RepoText.get().repoCommitMessage) .call(); - } catch (GitAPIException | IOException e) { + } catch (IOException e) { throw new ManifestErrorException(e); } } - private void prepareIndex(List projects, DirCache index, ObjectInserter inserter) throws IOException, GitAPIException { Config cfg = new Config(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java index e87bfe24e..54c527c03 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java @@ -104,9 +104,10 @@ public static DfsBlockCache getInstance() { private final ReentrantLock[] loadLocks; /** - * A separate pool of locks to prevent concurrent loads for same index or bitmap from PackFile. + * A separate pool of locks per pack extension to prevent concurrent loads + * for same index or bitmap from PackFile. */ - private final ReentrantLock[] refLocks; + private final ReentrantLock[][] refLocks; /** Maximum number of bytes the cache should hold. */ private final long maxBytes; @@ -173,13 +174,16 @@ private DfsBlockCache(DfsBlockCacheConfig cfg) { } table = new AtomicReferenceArray<>(tableSize); - loadLocks = new ReentrantLock[cfg.getConcurrencyLevel()]; + int concurrencyLevel = cfg.getConcurrencyLevel(); + loadLocks = new ReentrantLock[concurrencyLevel]; for (int i = 0; i < loadLocks.length; i++) { loadLocks[i] = new ReentrantLock(true /* fair */); } - refLocks = new ReentrantLock[cfg.getConcurrencyLevel()]; - for (int i = 0; i < refLocks.length; i++) { - refLocks[i] = new ReentrantLock(true /* fair */); + refLocks = new ReentrantLock[PackExt.values().length][concurrencyLevel]; + for (int i = 0; i < PackExt.values().length; i++) { + for (int j = 0; j < concurrencyLevel; ++j) { + refLocks[i][j] = new ReentrantLock(true /* fair */); + } } maxBytes = cfg.getBlockLimit(); @@ -636,7 +640,8 @@ private ReentrantLock lockFor(DfsStreamKey key, long position) { } private ReentrantLock lockForRef(DfsStreamKey key) { - return refLocks[(key.hash >>> 1) % refLocks.length]; + int slot = (key.hash >>> 1) % refLocks[key.packExtPos].length; + return refLocks[key.packExtPos][slot]; } private static AtomicLong[] newCounters() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java index b5bf03fcb..bb76df1d5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java @@ -415,8 +415,7 @@ void copyAsIs(PackOutputStream out, DfsObjectToPack src, try { readFully(src.offset, buf, 0, 20, ctx); } catch (IOException ioError) { - throw new StoredObjectRepresentationNotAvailableException(src, - ioError); + throw new StoredObjectRepresentationNotAvailableException(ioError); } int c = buf[0] & 0xff; final int typeCode = (c >> 4) & 7; @@ -537,12 +536,11 @@ void copyAsIs(PackOutputStream out, DfsObjectToPack src, Long.valueOf(src.offset), getFileName()), dataFormat); - throw new StoredObjectRepresentationNotAvailableException(src, + throw new StoredObjectRepresentationNotAvailableException( corruptObject); } catch (IOException ioError) { - throw new StoredObjectRepresentationNotAvailableException(src, - ioError); + throw new StoredObjectRepresentationNotAvailableException(ioError); } if (quickCopy != null) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java index 29d11104d..d8e191c4e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java @@ -23,10 +23,10 @@ import java.util.zip.Deflater; import org.eclipse.jgit.internal.storage.file.PackIndex; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ProgressMonitor; +import org.eclipse.jgit.transport.PackLock; import org.eclipse.jgit.transport.PackParser; import org.eclipse.jgit.transport.PackedObjectInfo; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java index 40c075ec5..93c620159 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java @@ -1530,7 +1530,8 @@ private void addRepackAllOption() { } /** - * @return {@code true} if number of packs > gc.autopacklimit (default 50) + * @return {@code true} if number of packs > gc.autopacklimit (default + * 50) */ boolean tooManyPacks() { int autopacklimit = repo.getConfig().getInt( @@ -1549,7 +1550,8 @@ boolean tooManyPacks() { * Quickly estimate number of loose objects, SHA1 is distributed evenly so * counting objects in one directory (bucket 17) is sufficient * - * @return {@code true} if number of loose objects > gc.auto (default 6700) + * @return {@code true} if number of loose objects > gc.auto (default + * 6700) */ boolean tooManyLooseObjects() { int auto = getLooseObjectLimit(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java index dba8ccd99..1c23ff20c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java @@ -34,6 +34,7 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.storage.pack.PackConfig; +import org.eclipse.jgit.transport.PackLock; import org.eclipse.jgit.transport.PackParser; import org.eclipse.jgit.transport.PackedObjectInfo; import org.eclipse.jgit.util.FileUtils; @@ -431,7 +432,7 @@ private PackLock renameAndOpenPack(String lockMessage) File packDir = new File(db.getDirectory(), "pack"); //$NON-NLS-1$ PackFile finalPack = new PackFile(packDir, id, PackExt.PACK); PackFile finalIdx = finalPack.create(PackExt.INDEX); - final PackLock keep = new PackLock(finalPack, db.getFS()); + final PackLockImpl keep = new PackLockImpl(finalPack, db.getFS()); if (!packDir.exists() && !packDir.mkdir() && !packDir.exists()) { // The objects/pack directory isn't present, and we are unable diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java index 5efd4c5bf..289c732f4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java @@ -521,12 +521,11 @@ private void copyAsIs2(PackOutputStream out, LocalObjectToPack src, Long.valueOf(src.offset), getPackFile()), dataFormat); - throw new StoredObjectRepresentationNotAvailableException(src, + throw new StoredObjectRepresentationNotAvailableException( corruptObject); } catch (IOException ioError) { - throw new StoredObjectRepresentationNotAvailableException(src, - ioError); + throw new StoredObjectRepresentationNotAvailableException(ioError); } if (quickCopy != null) { @@ -611,7 +610,7 @@ private synchronized void beginCopyAsIs(ObjectToPack otp) try { doOpen(); } catch (IOException thisPackNotValid) { - throw new StoredObjectRepresentationNotAvailableException(otp, + throw new StoredObjectRepresentationNotAvailableException( thisPackNotValid); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLock.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLockImpl.java similarity index 88% rename from org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLock.java rename to org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLockImpl.java index 482b143e3..7cc5f5054 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLock.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackLockImpl.java @@ -14,6 +14,7 @@ import java.io.IOException; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.transport.PackLock; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FileUtils; @@ -21,7 +22,7 @@ * Keeps track of a {@link org.eclipse.jgit.internal.storage.file.Pack}'s * associated .keep file. */ -public class PackLock { +public class PackLockImpl implements PackLock { private final File keepFile; /** @@ -32,7 +33,7 @@ public class PackLock { * @param fs * the filesystem abstraction used by the repository. */ - public PackLock(File packFile, FS fs) { + public PackLockImpl(File packFile, FS fs) { final File p = packFile.getParentFile(); final String n = packFile.getName(); keepFile = new File(p, n.substring(0, n.length() - 5) + ".keep"); //$NON-NLS-1$ @@ -59,12 +60,7 @@ public boolean lock(String msg) throws IOException { return lf.commit(); } - /** - * Remove the .keep file that holds this pack in place. - * - * @throws java.io.IOException - * if deletion of .keep file failed - */ + @Override public void unlock() throws IOException { FileUtils.delete(keepFile); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java index 2dbb7859b..648d4a182 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java @@ -142,7 +142,7 @@ public OpenSshConfigFile(@NonNull File home, @NonNull File config, * real host name, or it may just be a "Host" block in the * configuration file. * @param port - * the user supplied; <= 0 if none + * the user supplied; <= 0 if none * @param userName * the user supplied, may be {@code null} or empty if none given * @return the configuration for the requested name. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java index e4e7cd6e0..22e1f9818 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java @@ -18,6 +18,8 @@ import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; import java.text.MessageFormat; + +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.internal.JGitText; @@ -77,6 +79,9 @@ public String getCommitEncoding() { * {@code commit.template}. If no {@code i18n.commitEncoding} is specified, * UTF-8 fallback is used. * + * @param repository + * to resolve relative path in local git repo config + * * @return content of the commit template or {@code null} if not present. * @throws IOException * if the template file can not be read @@ -84,9 +89,10 @@ public String getCommitEncoding() { * if the template file does not exists * @throws ConfigInvalidException * if a {@code commitEncoding} is specified and is invalid + * @since 6.0 */ @Nullable - public String getCommitTemplateContent() + public String getCommitTemplateContent(@NonNull Repository repository) throws FileNotFoundException, IOException, ConfigInvalidException { if (commitTemplatePath == null) { @@ -94,11 +100,17 @@ public String getCommitTemplateContent() } File commitTemplateFile; + FS fileSystem = repository.getFS(); if (commitTemplatePath.startsWith("~/")) { //$NON-NLS-1$ - commitTemplateFile = FS.DETECTED.resolve(FS.DETECTED.userHome(), + commitTemplateFile = fileSystem.resolve(fileSystem.userHome(), commitTemplatePath.substring(2)); } else { - commitTemplateFile = FS.DETECTED.resolve(null, commitTemplatePath); + commitTemplateFile = fileSystem.resolve(null, commitTemplatePath); + } + if (!commitTemplateFile.isAbsolute()) { + commitTemplateFile = fileSystem.resolve( + repository.getWorkTree().getAbsoluteFile(), + commitTemplatePath); } Charset commitMessageEncoding = getEncoding(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java index d344deac2..f48e1e68c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -28,7 +28,6 @@ import org.eclipse.jgit.errors.RemoteRepositoryException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.MutableObjectId; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java index 47d156b66..f04e573fe 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java @@ -35,7 +35,6 @@ import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java index d06ef65c7..9dc062066 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java @@ -18,7 +18,6 @@ import java.util.Set; import org.eclipse.jgit.errors.TransportException; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java index 34bad6e02..7d7b3ee0a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java @@ -37,7 +37,6 @@ import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.LockFile; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.lib.BatchRefUpdate; import org.eclipse.jgit.lib.BatchingProgressMonitor; import org.eclipse.jgit.lib.Constants; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackLock.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackLock.java new file mode 100644 index 000000000..bf2140759 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackLock.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021 Thomas Wolf and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.transport; + +import java.io.IOException; + +/** + * A {@code PackLock} describes a {@code .keep} file that holds a pack in place. + * If {@link PackParser#parse(org.eclipse.jgit.lib.ProgressMonitor)} creates + * such a pack lock, it returns the lock so that it can be unlocked once the + * pack doesn't need a {@code .keep} file anymore. + * + * @since 6.0 + */ +public interface PackLock { + + /** + * Remove the {@code .keep} file that holds a pack in place. + * + * @throws java.io.IOException + * if deletion of the {@code .keep} file failed + */ + void unlock() throws IOException; +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java index 715cbb48f..e43ea0261 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java @@ -29,7 +29,6 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.TooLargeObjectInPackException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.internal.storage.pack.BinaryDelta; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.BatchingProgressMonitor; @@ -490,7 +489,7 @@ public ReceivedPackStatistics getReceivedPackStatistics() { * {@link #setLockMessage(String)}. * @throws java.io.IOException * the stream is malformed, or contains corrupt objects. - * @since 3.0 + * @since 6.0 */ public final PackLock parse(ProgressMonitor progress) throws IOException { return parse(progress, progress); @@ -509,7 +508,7 @@ public final PackLock parse(ProgressMonitor progress) throws IOException { * {@link #setLockMessage(String)}. * @throws java.io.IOException * the stream is malformed, or contains corrupt objects. - * @since 3.0 + * @since 6.0 */ public PackLock parse(ProgressMonitor receiving, ProgressMonitor resolving) throws IOException { 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 58f8895e0..871ba50a6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -48,7 +48,6 @@ import org.eclipse.jgit.errors.TooLargePackException; import org.eclipse.jgit.errors.UnpackException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.internal.submodule.SubmoduleValidator; import org.eclipse.jgit.internal.submodule.SubmoduleValidator.SubmoduleValidationException; import org.eclipse.jgit.internal.transport.connectivity.FullConnectivityChecker; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java index d98bd2307..1226a6b5e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java @@ -28,7 +28,7 @@ public interface SshConfigStore { * @param hostName * to look up * @param port - * the user supplied; <= 0 if none + * the user supplied; <= 0 if none * @param userName * the user supplied, may be {@code null} or empty if none given * @return the configuration for the requested name. @@ -68,7 +68,7 @@ public interface SshConfigStore { * @param hostName * host name to look up * @param port - * port number; <= 0 if none + * port number; <= 0 if none * @param userName * the user name, may be {@code null} or empty if none given * @return the configuration for the requested name. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java index a6b20451d..d67fe074e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java @@ -32,7 +32,6 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.ObjectDirectory; import org.eclipse.jgit.internal.storage.file.PackIndex; -import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.internal.storage.file.UnpackedObject; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; 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 dd656e5f2..d0007ec21 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -59,6 +59,8 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -94,6 +96,9 @@ public abstract class FS { */ protected static final Entry[] NO_ENTRIES = {}; + private static final Pattern VERSION = Pattern + .compile("\\s(\\d+)\\.(\\d+)\\.(\\d+)"); //$NON-NLS-1$ + private volatile Boolean supportSymlinks; /** @@ -1516,26 +1521,76 @@ protected File discoverGitSystemConfig() { return null; } - // Trick Git into printing the path to the config file by using "echo" - // as the editor. - Map env = new HashMap<>(); - env.put("GIT_EDITOR", "echo"); //$NON-NLS-1$ //$NON-NLS-2$ + if (parseVersion(v) < makeVersion(2, 8, 0)) { + // --show-origin was introduced in git 2.8.0. For older git: trick + // it into printing the path to the config file by using "echo" as + // the editor. + Map env = new HashMap<>(); + env.put("GIT_EDITOR", "echo"); //$NON-NLS-1$ //$NON-NLS-2$ + String w; + try { + w = readPipe(gitExe.getParentFile(), + new String[] { gitExe.getPath(), "config", "--system", //$NON-NLS-1$ //$NON-NLS-2$ + "--edit" }, //$NON-NLS-1$ + SystemReader.getInstance().getDefaultCharset().name(), + env); + } catch (CommandFailedException e) { + LOG.warn(e.getMessage()); + return null; + } + if (StringUtils.isEmptyOrNull(w)) { + return null; + } + + return new File(w); + } String w; try { w = readPipe(gitExe.getParentFile(), new String[] { gitExe.getPath(), "config", "--system", //$NON-NLS-1$ //$NON-NLS-2$ - "--edit" }, //$NON-NLS-1$ - SystemReader.getInstance().getDefaultCharset().name(), env); + "--show-origin", "--list", "-z" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + SystemReader.getInstance().getDefaultCharset().name()); } catch (CommandFailedException e) { LOG.warn(e.getMessage()); return null; } - if (StringUtils.isEmptyOrNull(w)) { + if (w == null) { return null; } + // We get NUL-terminated items; the first one will be a file name, + // prefixed by "file:". (Using -z is crucial, otherwise git quotes file + // names with special characters.) + int nul = w.indexOf(0); + if (nul <= 0) { + return null; + } + w = w.substring(0, nul); + int colon = w.indexOf(':'); + if (colon < 0) { + return null; + } + w = w.substring(colon + 1); + return w.isEmpty() ? null : new File(w); + } - return new File(w); + private long parseVersion(String version) { + Matcher m = VERSION.matcher(version); + if (m.find()) { + try { + return makeVersion( + Integer.parseInt(m.group(1)), + Integer.parseInt(m.group(2)), + Integer.parseInt(m.group(3))); + } catch (NumberFormatException e) { + // Ignore + } + } + return -1; + } + + private long makeVersion(int major, int minor, int patch) { + return ((major * 10_000L) + minor) * 10_000L + patch; } /** diff --git a/pom.xml b/pom.xml index f7629411b..f5b66d13c 100644 --- a/pom.xml +++ b/pom.xml @@ -162,7 +162,7 @@ 1.21 4.3.1 3.1.0 - 9.4.44.v20210927 + 10.0.6 0.15.3 4.5.13 4.4.14