diff options
282 files changed, 5516 insertions, 2000 deletions
@@ -7,3 +7,4 @@ Saša Živkov <sasa.zivkov@sap.com> Sasa Zivkov <zivkov@gmail.com> Shawn Pearce <spearce@spearce.org> Shawn O. Pearce <sop@google.com> Shawn Pearce <spearce@spearce.org> Shawn Pearce <sop@google.com> Shawn Pearce <spearce@spearce.org> Shawn O. Pearce <spearce@spearce.org> +Terry Parker <tparker@google.com> tparker <tparker@google.com> @@ -11,8 +11,8 @@ load( maven_jar( name = "jsch", - artifact = "com.jcraft:jsch:0.1.53", - sha1 = "658b682d5c817b27ae795637dfec047c63d29935", + artifact = "com.jcraft:jsch:0.1.54", + sha1 = "da3584329a263616e277e15462b387addd1b208d", ) maven_jar( @@ -29,26 +29,26 @@ maven_jar( maven_jar( name = "httpclient", - artifact = "org.apache.httpcomponents:httpclient:4.5.2", - sha1 = "733db77aa8d9b2d68015189df76ab06304406e50", + artifact = "org.apache.httpcomponents:httpclient:4.5.5", + sha1 = "1603dfd56ebcd583ccdf337b6c3984ac55d89e58", ) maven_jar( name = "httpcore", - artifact = "org.apache.httpcomponents:httpcore:4.4.6", - sha1 = "e3fd8ced1f52c7574af952e2e6da0df8df08eb82", + artifact = "org.apache.httpcomponents:httpcore:4.4.9", + sha1 = "a86ce739e5a7175b4b234c290a00a5fdb80957a0", ) maven_jar( name = "commons-codec", - artifact = "commons-codec:commons-codec:1.4", - sha1 = "4216af16d38465bbab0f3dff8efa14204f7a399a", + artifact = "commons-codec:commons-codec:1.10", + sha1 = "4b95f4897fa13f2cd904aee711aeafc0c5295cd8", ) maven_jar( name = "commons-logging", - artifact = "commons-logging:commons-logging:1.1.3", - sha1 = "f6f66e966c70a83ffbdb6f17a0919eaf7c8aca7f", + artifact = "commons-logging:commons-logging:1.2", + sha1 = "4bfc12adfe4842bf07b657f0369c4cb522955686", ) maven_jar( @@ -89,8 +89,8 @@ maven_jar( maven_jar( name = "junit", - artifact = "junit:junit:4.11", - sha1 = "4e031bb61df09069aeb2bffb4019e7a5034a4ee0", + artifact = "junit:junit:4.12", + sha1 = "2973d150c0dc1fefe998f834810d68f278ea58ec", ) maven_jar( @@ -111,46 +111,46 @@ maven_jar( sha1 = "3edcfe49d2c6053a70a2a47e4e1c2f94998a49cf", ) -JETTY_VER = "9.4.8.v20171121" +JETTY_VER = "9.4.11.v20180605" maven_jar( name = "jetty-servlet", artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER, - sha1 = "bbbb9b5de08f468c7b9b3de6aea0b098d2c679b6", - src_sha1 = "6ef1e65a5af7ab2d79ba6043923affdaeaafb1e5", + sha1 = "66d31900fcfc70e3666f0b3335b6660635154f98", + src_sha1 = "930c50de49b9c258d5f0329426cbcac4d3143497", ) maven_jar( name = "jetty-security", artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER, - sha1 = "e8350eec683b55494287f06740543e4be6f75425", - src_sha1 = "e3a879d8675fa10bc305e7a59006f1d09db04a68", + sha1 = "926def86d31ee07ca4b4658833dc6ee6918b8e86", + src_sha1 = "019bc7c2a366cbb201950f24dd64d9d9a49b6840", ) maven_jar( name = "jetty-server", artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER, - sha1 = "34614bd9a29de57ef28ca31f1f2b49a412af196d", - src_sha1 = "fef49ac6b2bbc6d142dc0be34f68f0fb0792d52b", + sha1 = "58353c2f27515b007fc83ae22002feb34fc24714", + src_sha1 = "e7d832d74df616137755996b41bc28bb82b3bc42", ) maven_jar( name = "jetty-http", artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER, - sha1 = "9879d6c4e37400bf43f0cd4b3c6e34a3ba409864", - src_sha1 = "5e746cd0ccb732eef0427c8c4b9dcb034e26c61b", + sha1 = "20c35f5336befe35b0bd5c4a63e07170fe7872d7", + src_sha1 = "5bc30d1f7e8c4456c22cc85999b8cafd3741bdff", ) maven_jar( name = "jetty-io", artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER, - sha1 = "d3fe2dfa62f52ee91ff07cb359f63387e0e30b40", - src_sha1 = "41f25e1e1bba14ab0d3415488fa189f09c27a1cf", + sha1 = "d164de1dac18c4ca80a1b783d879c97449909c3b", + src_sha1 = "02c0caba292b1cb74cec1d36c6f91dc863c89b5a", ) maven_jar( name = "jetty-util", artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER, - sha1 = "d6ec1a1613c7fa72aa6bf5d8c204750afbc3df3b", - src_sha1 = "a74ecb43f96b2e21852f6908604316d7348a16ad", + sha1 = "f0f25aa2f27d618a04bc7356fa247ae4a05245b3", + src_sha1 = "4e5c4c483cfd9804c2fc5d5751866243bbb9d740", ) @@ -51,6 +51,7 @@ java_library( name = "httpcore", visibility = [ "//org.eclipse.jgit.http.apache:__pkg__", + "//org.eclipse.jgit.http.test:__pkg__", "//org.eclipse.jgit.lfs.server:__pkg__", "//org.eclipse.jgit.lfs.server.test:__pkg__", "//org.eclipse.jgit.pgm:__pkg__", diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF index 268baee976..4d1a830c2a 100644 --- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF @@ -4,13 +4,13 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.ant.test Bundle-SymbolicName: org.eclipse.jgit.ant.test -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.ant.tasks;version="[5.0.4,5.1.0)", - org.eclipse.jgit.junit;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", + org.eclipse.jgit.ant.tasks;version="[5.1.3,5.2.0)", + org.eclipse.jgit.junit;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", org.hamcrest.core;version="[1.1.0,2.0.0)", org.junit;version="[4.12,5.0.0)" diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml index 4bfbc9e6df..69433bed9a 100644 --- a/org.eclipse.jgit.ant.test/pom.xml +++ b/org.eclipse.jgit.ant.test/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ant.test</artifactId> diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF index 6df309139b..c507f01c86 100644 --- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF @@ -3,11 +3,11 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.ant Bundle-SymbolicName: org.eclipse.jgit.ant -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.storage.file;version="[5.0.4,5.1.0)" + org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)" Bundle-Localization: plugin Bundle-Vendor: %Provider-Name -Export-Package: org.eclipse.jgit.ant.tasks;version="5.0.4"; +Export-Package: org.eclipse.jgit.ant.tasks;version="5.1.3"; uses:="org.apache.tools.ant.types,org.apache.tools.ant" diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml index a288360f32..88c1759ae2 100644 --- a/org.eclipse.jgit.ant/pom.xml +++ b/org.eclipse.jgit.ant/pom.xml @@ -48,7 +48,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ant</artifactId> diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF index 3285ee4f0a..427effd745 100644 --- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.archive Bundle-SymbolicName: org.eclipse.jgit.archive -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -13,15 +13,15 @@ Import-Package: org.apache.commons.compress.archivers;version="[1.4,2.0)", org.apache.commons.compress.compressors.bzip2;version="[1.4,2.0)", org.apache.commons.compress.compressors.gzip;version="[1.4,2.0)", org.apache.commons.compress.compressors.xz;version="[1.4,2.0)", - org.eclipse.jgit.api;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", + org.eclipse.jgit.api;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", org.osgi.framework;version="[1.3.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-Activator: org.eclipse.jgit.archive.FormatActivator -Export-Package: org.eclipse.jgit.archive;version="5.0.4"; +Export-Package: org.eclipse.jgit.archive;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.api, org.apache.commons.compress.archivers, diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF index f85551e0d3..3bdd424a3d 100644 --- a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF @@ -3,5 +3,5 @@ Bundle-ManifestVersion: 2 Bundle-Name: org.eclipse.jgit.archive - Sources Bundle-SymbolicName: org.eclipse.jgit.archive.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 5.0.4.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.0.4.qualifier";roots="." +Bundle-Version: 5.1.3.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.1.3.qualifier";roots="." diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml index 4bfa1761a4..9eb383d68d 100644 --- a/org.eclipse.jgit.archive/pom.xml +++ b/org.eclipse.jgit.archive/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.archive</artifactId> diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF index 69fb47cb06..dbf7fefa8e 100644 --- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.http.apache Bundle-SymbolicName: org.eclipse.jgit.http.apache -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Localization: plugin Bundle-Vendor: %Provider-Name @@ -23,10 +23,10 @@ Import-Package: org.apache.http;version="[4.3.0,5.0.0)", org.apache.http.impl.client;version="[4.3.0,5.0.0)", org.apache.http.impl.conn;version="[4.3.0,5.0.0)", org.apache.http.params;version="[4.3.0,5.0.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.http;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)" -Export-Package: org.eclipse.jgit.transport.http.apache;version="5.0.4"; + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.http;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)" +Export-Package: org.eclipse.jgit.transport.http.apache;version="5.1.3"; uses:="org.apache.http.client, org.eclipse.jgit.transport.http, org.apache.http.entity, diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml index bc71faaa37..15345b2f02 100644 --- a/org.eclipse.jgit.http.apache/pom.xml +++ b/org.eclipse.jgit.http.apache/pom.xml @@ -48,7 +48,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.apache</artifactId> diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java index 7f1fecb9bf..77c5dc0f3e 100644 --- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java +++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java @@ -272,10 +272,14 @@ public class HttpClientConnection implements HttpConnection { public Map<String, List<String>> getHeaderFields() { Map<String, List<String>> ret = new HashMap<>(); for (Header hdr : resp.getAllHeaders()) { - List<String> list = new LinkedList<>(); - for (HeaderElement hdrElem : hdr.getElements()) + List<String> list = ret.get(hdr.getName()); + if (list == null) { + list = new LinkedList<>(); + ret.put(hdr.getName(), list); + } + for (HeaderElement hdrElem : hdr.getElements()) { list.add(hdrElem.toString()); - ret.put(hdr.getName(), list); + } } return ret; } diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF index c97b927de0..37f5b1df8c 100644 --- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF @@ -3,13 +3,13 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.http.server Bundle-SymbolicName: org.eclipse.jgit.http.server -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.http.server;version="5.0.4", - org.eclipse.jgit.http.server.glue;version="5.0.4"; +Export-Package: org.eclipse.jgit.http.server;version="5.1.3", + org.eclipse.jgit.http.server.glue;version="5.1.3"; uses:="javax.servlet,javax.servlet.http", - org.eclipse.jgit.http.server.resolver;version="5.0.4"; + org.eclipse.jgit.http.server.resolver;version="5.1.3"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.lib, org.eclipse.jgit.transport, @@ -18,12 +18,12 @@ Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: javax.servlet;version="[2.5.0,3.2.0)", javax.servlet.http;version="[2.5.0,3.2.0)", - org.eclipse.jgit.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.resolver;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)" + org.eclipse.jgit.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.resolver;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)" diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml index 6f700815e2..d27fecf64e 100644 --- a/org.eclipse.jgit.http.server/pom.xml +++ b/org.eclipse.jgit.http.server/pom.xml @@ -52,7 +52,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.server</artifactId> diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java index 0f4633b5e3..1a9d192450 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.http.server; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.http.server.ServletUtils.getRepository; import java.io.IOException; @@ -73,7 +74,7 @@ class InfoRefsServlet extends HttpServlet { final Repository db = getRepository(req); try (OutputStreamWriter out = new OutputStreamWriter( new SmartOutputStream(req, rsp, true), - Constants.CHARSET)) { + UTF_8)) { final RefAdvertiser adv = new RefAdvertiser() { @Override protected void writeOne(CharSequence line) diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java index 195dff9613..75611eec95 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java @@ -77,7 +77,7 @@ abstract class SmartServiceInfoRefs implements Filter { SmartServiceInfoRefs(String service, List<Filter> filters) { this.svc = service; - this.filters = filters.toArray(new Filter[filters.size()]); + this.filters = filters.toArray(new Filter[0]); } /** {@inheritDoc} */ diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java index 18650eb95b..f16749775f 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java @@ -98,7 +98,7 @@ abstract class ServletBinderImpl implements ServletBinder { * @return the configured filters; zero-length array if none. */ protected Filter[] getFilters() { - return filters.toArray(new Filter[filters.size()]); + return filters.toArray(new Filter[0]); } /** @return the pipeline that matches and executes this chain. */ diff --git a/org.eclipse.jgit.http.test/BUILD b/org.eclipse.jgit.http.test/BUILD index 85a22422be..dcffa066d0 100644 --- a/org.eclipse.jgit.http.test/BUILD +++ b/org.eclipse.jgit.http.test/BUILD @@ -10,6 +10,7 @@ junit_tests( deps = [ ":helpers", "//lib:commons-logging", + "//lib:httpcore", "//lib:jetty-http", "//lib:jetty-io", "//lib:jetty-security", diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF index 8bb282e183..7bfa910295 100644 --- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.http.test Bundle-SymbolicName: org.eclipse.jgit.http.test -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -11,6 +11,9 @@ Import-Package: javax.servlet;version="[2.5.0,3.2.0)", javax.servlet.http;version="[2.5.0,3.2.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.3.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)", @@ -25,25 +28,25 @@ Import-Package: javax.servlet;version="[2.5.0,3.2.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.jgit.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.http.server;version="[5.0.4,5.1.0)", - org.eclipse.jgit.http.server.glue;version="[5.0.4,5.1.0)", - org.eclipse.jgit.http.server.resolver;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.reftable;version="[5.0.4,5.1.0)", - org.eclipse.jgit.junit;version="[5.0.4,5.1.0)", - org.eclipse.jgit.junit.http;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.http;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.http.apache;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.resolver;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", + org.eclipse.jgit.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.http.server;version="[5.1.3,5.2.0)", + org.eclipse.jgit.http.server.glue;version="[5.1.3,5.2.0)", + org.eclipse.jgit.http.server.resolver;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.reftable;version="[5.1.3,5.2.0)", + org.eclipse.jgit.junit;version="[5.1.3,5.2.0)", + org.eclipse.jgit.junit.http;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.http;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.http.apache;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.resolver;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", org.hamcrest;version="[1.1.0,2.0.0)", org.hamcrest.core;version="[1.1.0,2.0.0)", org.junit;version="[4.12,5.0.0)", diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml index 7b832405b5..94e5f3b47f 100644 --- a/org.eclipse.jgit.http.test/pom.xml +++ b/org.eclipse.jgit.http.test/pom.xml @@ -51,7 +51,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.test</artifactId> diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java index ef059bf2a3..53626b1b2e 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java @@ -175,7 +175,9 @@ public class HttpClientTests extends HttpTestCase { } catch (NoRemoteRepositoryException err) { String exp = uri + ": " + uri + "/info/refs?service=git-upload-pack not found"; - assertEquals(exp, err.getMessage()); + assertNotNull(err.getMessage()); + assertTrue("Unexpected error message", + err.getMessage().startsWith(exp)); } } } @@ -191,7 +193,9 @@ public class HttpClientTests extends HttpTestCase { } catch (NoRemoteRepositoryException err) { String exp = uri + ": " + uri + "/info/refs?service=git-upload-pack not found"; - assertEquals(exp, err.getMessage()); + assertNotNull(err.getMessage()); + assertTrue("Unexpected error message", + err.getMessage().startsWith(exp)); } } } @@ -363,7 +367,7 @@ public class HttpClientTests extends HttpTestCase { c.setRequestMethod("GET"); c.setRequestProperty("Git-Protocol", "version=2"); c.connect(); - assertThat(c.getResponseCode(), is(200)); + assertEquals(200, c.getResponseCode()); PacketLineIn pckIn = new PacketLineIn(c.getInputStream()); @@ -384,7 +388,7 @@ public class HttpClientTests extends HttpTestCase { c.setRequestMethod("GET"); c.setRequestProperty("Git-Protocol", "version=2"); c.connect(); - assertThat(c.getResponseCode(), is(200)); + assertEquals(200, c.getResponseCode()); PacketLineIn pckIn = new PacketLineIn(c.getInputStream()); assertThat(pckIn.readString(), is("version 2")); @@ -415,12 +419,12 @@ public class HttpClientTests extends HttpTestCase { // properly. Tests for other commands go in // UploadPackTest.java. - OutputStream os = c.getOutputStream(); - PacketLineOut pckOut = new PacketLineOut(os); - pckOut.writeString("command=ls-refs"); - pckOut.writeDelim(); - pckOut.end(); - os.close(); + try (OutputStream os = c.getOutputStream()) { + PacketLineOut pckOut = new PacketLineOut(os); + pckOut.writeString("command=ls-refs"); + pckOut.writeDelim(); + pckOut.end(); + } PacketLineIn pckIn = new PacketLineIn(c.getInputStream()); @@ -430,6 +434,6 @@ public class HttpClientTests extends HttpTestCase { assertTrue(s.matches("[0-9a-f]{40} [A-Za-z/]*")); } - assertThat(c.getResponseCode(), is(200)); + assertEquals(200, c.getResponseCode()); } } 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 42db0fecde..51aa5f2ba7 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 @@ -43,7 +43,7 @@ package org.eclipse.jgit.http.test; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_LENGTH; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE; @@ -1081,7 +1081,7 @@ public class SmartClientSmartServerTest extends HttpTestCase { public void testInvalidWant() throws Exception { @SuppressWarnings("resource") ObjectId id = new ObjectInserter.Formatter().idFor(Constants.OBJ_BLOB, - "testInvalidWant".getBytes(CHARSET)); + "testInvalidWant".getBytes(UTF_8)); Repository dst = createBareRepository(); try (Transport t = Transport.open(dst, remoteURI); 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 new file mode 100644 index 0000000000..72c4921de6 --- /dev/null +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/transport/http/apache/HttpClientConnectionTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2018 Gabriel Couto <gmcouto@gmail.com> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.transport.http.apache; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.StatusLine; +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() + throws MalformedURLException { + HttpResponse responseMock = new HttpResponseMock(); + String headerField = "WWW-Authenticate"; + responseMock.addHeader(headerField, "Basic"); + responseMock.addHeader(headerField, "Digest"); + responseMock.addHeader(headerField, "NTLM"); + HttpClientConnection connection = new HttpClientConnection( + "http://0.0.0.0/"); + connection.resp = responseMock; + List<String> headerValues = connection.getHeaderFields() + .get(headerField); + assertEquals(3, headerValues.size()); + assertTrue(headerValues.contains("Basic")); + assertTrue(headerValues.contains("Digest")); + assertTrue(headerValues.contains("NTLM")); + } + + private class HttpResponseMock extends AbstractHttpMessage + implements HttpResponse { + @Override + public StatusLine getStatusLine() { + throw new UnsupportedOperationException(); + } + + @Override + public void setStatusLine(StatusLine statusLine) { + throw new UnsupportedOperationException(); + } + + @Override + public void setStatusLine(ProtocolVersion protocolVersion, int i) { + throw new UnsupportedOperationException(); + } + + @Override + public void setStatusLine(ProtocolVersion protocolVersion, int i, + String s) { + throw new UnsupportedOperationException(); + } + + @Override + public void setStatusCode(int i) throws IllegalStateException { + throw new UnsupportedOperationException(); + } + + @Override + public void setReasonPhrase(String s) throws IllegalStateException { + throw new UnsupportedOperationException(); + } + + @Override + public HttpEntity getEntity() { + throw new UnsupportedOperationException(); + } + + @Override + public void setEntity(HttpEntity httpEntity) { + throw new UnsupportedOperationException(); + } + + @Override + public Locale getLocale() { + throw new UnsupportedOperationException(); + } + + @Override + public void setLocale(Locale locale) { + throw new UnsupportedOperationException(); + } + + @Override + public ProtocolVersion getProtocolVersion() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF index a68d152554..2a8f61f3ed 100644 --- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.junit.http Bundle-SymbolicName: org.eclipse.jgit.junit.http -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy @@ -22,16 +22,16 @@ Import-Package: javax.servlet;version="[2.5.0,3.2.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.jgit.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.http.server;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.junit;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.resolver;version="[5.0.4,5.1.0)", + org.eclipse.jgit.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.http.server;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.junit;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.resolver;version="[5.1.3,5.2.0)", org.junit;version="[4.12,5.0.0)" -Export-Package: org.eclipse.jgit.junit.http;version="5.0.4"; +Export-Package: org.eclipse.jgit.junit.http;version="5.1.3"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.junit, javax.servlet.http, diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml index eb7d02ffe4..e16f4e9e57 100644 --- a/org.eclipse.jgit.junit.http/pom.xml +++ b/org.eclipse.jgit.junit.http/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit.http</artifactId> 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 9309fe7071..9aef086b78 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 @@ -349,7 +349,7 @@ public class AppServer { sec.setAuthenticator(authType); sec.setLoginService(users); sec.setConstraintMappings( - mappings.toArray(new ConstraintMapping[mappings.size()])); + mappings.toArray(new ConstraintMapping[0])); sec.setHandler(ctx); contexts.removeHandler(ctx); diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF index 749f8fe984..f8e77af300 100644 --- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF @@ -3,31 +3,31 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.junit Bundle-SymbolicName: org.eclipse.jgit.junit -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.api;version="[5.0.4,5.1.0)", - org.eclipse.jgit.api.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.dircache;version="[5.0.4,5.1.0)", - org.eclipse.jgit.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.pack;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.merge;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk.filter;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util.io;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util.time;version="[5.0.4,5.1.0)", +Import-Package: org.eclipse.jgit.api;version="[5.1.3,5.2.0)", + org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.dircache;version="[5.1.3,5.2.0)", + org.eclipse.jgit.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.pack;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.merge;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util.io;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util.time;version="[5.1.3,5.2.0)", org.junit;version="[4.12,5.0.0)", org.junit.rules;version="[4.12,5.0.0)", org.junit.runner;version="[4.12,5.0.0)", org.junit.runners.model;version="[4.12,5.0.0)" -Export-Package: org.eclipse.jgit.junit;version="5.0.4"; +Export-Package: org.eclipse.jgit.junit;version="5.1.3"; uses:="org.eclipse.jgit.dircache, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, @@ -36,4 +36,4 @@ Export-Package: org.eclipse.jgit.junit;version="5.0.4"; org.eclipse.jgit.util, org.eclipse.jgit.storage.file, org.eclipse.jgit.api", - org.eclipse.jgit.junit.time;version="5.0.4" + org.eclipse.jgit.junit.time;version="5.1.3" diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml index 30ce0b3d41..60dceb203c 100644 --- a/org.eclipse.jgit.junit/pom.xml +++ b/org.eclipse.jgit.junit/pom.xml @@ -52,7 +52,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit</artifactId> diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java index a102da1f49..b59b71499d 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.junit; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.File; import java.io.FileNotFoundException; @@ -246,7 +246,7 @@ public abstract class JGitTestUtil { throws IOException { FileUtils.mkdirs(f.getParentFile(), true); try (Writer w = new OutputStreamWriter(new FileOutputStream(f), - CHARSET)) { + UTF_8)) { w.write(body); } } @@ -263,7 +263,7 @@ public abstract class JGitTestUtil { */ public static String read(File file) throws IOException { final byte[] body = IO.readFully(file); - return new String(body, 0, body.length, CHARSET); + return new String(body, 0, body.length, UTF_8); } /** diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java index 6cdd0eb23c..12b2169500 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.junit; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; @@ -352,7 +352,7 @@ public abstract class LocalDiskRepositoryTestCase { if (0 != (includedOptions & CONTENT)) { sb.append(", content:" + new String(repo.open(entry.getObjectId(), - Constants.OBJ_BLOB).getCachedBytes(), CHARSET)); + Constants.OBJ_BLOB).getCachedBytes(), UTF_8)); } if (0 != (includedOptions & ASSUME_UNCHANGED)) sb.append(", assume-unchanged:" diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java index e983e5dfb6..95fe18b83c 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java @@ -46,7 +46,7 @@ package org.eclipse.jgit.junit; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import java.io.File; @@ -192,7 +192,7 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase { protected static void checkFile(File f, String checkData) throws IOException { try (Reader r = new InputStreamReader(new FileInputStream(f), - CHARSET)) { + UTF_8)) { if (checkData.length() > 0) { char[] data = new char[checkData.length()]; assertEquals(data.length, r.read(data)); diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java index d23c0d3c22..c9fa2f506c 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.junit; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -268,7 +268,7 @@ public class TestRepository<R extends Repository> { * @throws Exception */ public RevBlob blob(String content) throws Exception { - return blob(content.getBytes(CHARSET)); + return blob(content.getBytes(UTF_8)); } /** @@ -276,7 +276,7 @@ public class TestRepository<R extends Repository> { * * @param content * binary file content. - * @return reference to the blob. + * @return the new, fully parsed blob. * @throws Exception */ public RevBlob blob(byte[] content) throws Exception { @@ -285,7 +285,7 @@ public class TestRepository<R extends Repository> { id = ins.insert(Constants.OBJ_BLOB, content); ins.flush(); } - return pool.lookupBlob(id); + return (RevBlob) pool.parseAny(id); } /** @@ -312,21 +312,22 @@ public class TestRepository<R extends Repository> { * @param entries * the files to include in the tree. The collection does not need * to be sorted properly and may be empty. - * @return reference to the tree specified by the entry list. + * @return the new, fully parsed tree specified by the entry list. * @throws Exception */ public RevTree tree(DirCacheEntry... entries) throws Exception { final DirCache dc = DirCache.newInCore(); final DirCacheBuilder b = dc.builder(); - for (DirCacheEntry e : entries) + for (DirCacheEntry e : entries) { b.add(e); + } b.finish(); ObjectId root; try (ObjectInserter ins = inserter) { root = dc.writeTree(ins); ins.flush(); } - return pool.lookupTree(root); + return pool.parseTree(root); } /** @@ -422,7 +423,7 @@ public class TestRepository<R extends Repository> { * the root tree for the commit. * @param parents * zero or more parents of the commit. - * @return the new commit. + * @return the new, fully parsed commit. * @throws Exception */ public RevCommit commit(final int secDelta, final RevTree tree, @@ -442,7 +443,7 @@ public class TestRepository<R extends Repository> { id = ins.insert(c); ins.flush(); } - return pool.lookupCommit(id); + return pool.parseCommit(id); } /** @@ -467,7 +468,7 @@ public class TestRepository<R extends Repository> { * with {@code refs/tags/}. * @param dst * object the tag should be pointed at. - * @return the annotated tag object. + * @return the new, fully parsed annotated tag object. * @throws Exception */ public RevTag tag(String name, RevObject dst) throws Exception { @@ -481,7 +482,7 @@ public class TestRepository<R extends Repository> { id = ins.insert(t); ins.flush(); } - return (RevTag) pool.lookupAny(id, Constants.OBJ_TAG); + return pool.parseTag(id); } /** @@ -705,8 +706,8 @@ public class TestRepository<R extends Repository> { * * @param id * commit-ish to cherry-pick. - * @return newly created commit, or null if no work was done due to the - * resulting tree being identical. + * @return the new, fully parsed commit, or null if no work was done due to + * the resulting tree being identical. * @throws Exception */ public RevCommit cherryPick(AnyObjectId id) throws Exception { @@ -757,7 +758,7 @@ public class TestRepository<R extends Repository> { public void updateServerInfo() throws Exception { if (db instanceof FileRepository) { final FileRepository fr = (FileRepository) db; - RefWriter rw = new RefWriter(fr.getAllRefs().values()) { + RefWriter rw = new RefWriter(fr.getRefDatabase().getRefs()) { @Override protected void writeFile(String name, byte[] bin) throws IOException { @@ -852,7 +853,7 @@ public class TestRepository<R extends Repository> { for (RevObject o : tips) ow.markStart(ow.parseAny(o)); } else { - for (Ref r : db.getAllRefs().values()) + for (Ref r : db.getRefDatabase().getRefs()) ow.markStart(ow.parseAny(r.getObjectId())); } @@ -905,7 +906,7 @@ public class TestRepository<R extends Repository> { final File pack, idx; try (PackWriter pw = new PackWriter(db)) { Set<ObjectId> all = new HashSet<>(); - for (Ref r : db.getAllRefs().values()) + for (Ref r : db.getRefDatabase().getRefs()) all.add(r.getObjectId()); pw.preparePack(m, all, PackWriter.NONE); @@ -1197,7 +1198,7 @@ public class TestRepository<R extends Repository> { commitId = ins.insert(c); ins.flush(); } - self = pool.lookupCommit(commitId); + self = pool.parseCommit(commitId); if (branch != null) branch.update(self); 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 c805f75e3c..f4fb262a3e 100644 --- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.lfs.server.test Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -28,24 +28,24 @@ Import-Package: javax.servlet;version="[3.1.0,4.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.jgit.api;version="[5.0.4,5.1.0)", - org.eclipse.jgit.api.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.junit;version="[5.0.4,5.1.0)", - org.eclipse.jgit.junit.http;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.server;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.server.fs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.test;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk.filter;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", + org.eclipse.jgit.api;version="[5.1.3,5.2.0)", + org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.junit;version="[5.1.3,5.2.0)", + org.eclipse.jgit.junit.http;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.server;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.server.fs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.test;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", org.hamcrest.core;version="[1.1.0,2.0.0)", org.junit;version="[4.12,5.0.0)", org.junit.rules;version="[4.12,5.0.0)", diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml index dee3199984..4fa8d7680e 100644 --- a/org.eclipse.jgit.lfs.server.test/pom.xml +++ b/org.eclipse.jgit.lfs.server.test/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.server.test</artifactId> @@ -111,7 +111,6 @@ <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> - <version>4.3.6</version> </dependency> </dependencies> diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java index 50a06f94d6..10823b8788 100644 --- a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java +++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.lfs.server.fs; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import java.io.BufferedInputStream; @@ -211,11 +211,11 @@ public abstract class LfsServerTest { if (buf.hasArray()) { error = new String(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), - CHARSET); + UTF_8); } else { final byte[] b = new byte[buf.remaining()]; buf.duplicate().get(b); - error = new String(b, CHARSET); + error = new String(b, UTF_8); } } catch (IOException e) { error = statusLine.getReasonPhrase(); diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs index 112e3c3187..c0030ded71 100644 --- a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs +++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.pde.api.tools.prefs @@ -81,7 +81,7 @@ METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error -MISSING_EE_DESCRIPTIONS=Error +MISSING_EE_DESCRIPTIONS=Warning TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF index 14d3ab89e8..31b01a93b2 100644 --- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF @@ -3,19 +3,19 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.lfs.server Bundle-SymbolicName: org.eclipse.jgit.lfs.server -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs.server;version="5.0.4"; +Export-Package: org.eclipse.jgit.lfs.server;version="5.1.3"; uses:="javax.servlet.http, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.fs;version="5.0.4"; + org.eclipse.jgit.lfs.server.fs;version="5.1.3"; uses:="javax.servlet, javax.servlet.http, org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.internal;version="5.0.4";x-internal:=true, - org.eclipse.jgit.lfs.server.s3;version="5.0.4"; + org.eclipse.jgit.lfs.server.internal;version="5.1.3";x-internal:=true, + org.eclipse.jgit.lfs.server.s3;version="5.1.3"; uses:="org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -25,15 +25,15 @@ Import-Package: com.google.gson;version="[2.8.0,3.0.0)", javax.servlet.http;version="[3.1.0,4.0.0)", org.apache.http;version="[4.3.0,5.0.0)", org.apache.http.client;version="[4.3.0,5.0.0)", - org.eclipse.jgit.annotations;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.internal;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.http;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.http.apache;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", + org.eclipse.jgit.annotations;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.internal;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.http;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.http.apache;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", org.slf4j;version="[1.7.0,2.0.0)" diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml index 7c81c1a5d7..910c13aa2f 100644 --- a/org.eclipse.jgit.lfs.server/pom.xml +++ b/org.eclipse.jgit.lfs.server/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.server</artifactId> diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java index d22d45967e..c7f55dd3c1 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.lfs.server; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.http.HttpStatus.SC_FORBIDDEN; import static org.apache.http.HttpStatus.SC_INSUFFICIENT_STORAGE; import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR; @@ -202,10 +202,10 @@ public abstract class LfsProtocolServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Writer w = new BufferedWriter( - new OutputStreamWriter(res.getOutputStream(), CHARSET)); + new OutputStreamWriter(res.getOutputStream(), UTF_8)); Reader r = new BufferedReader( - new InputStreamReader(req.getInputStream(), CHARSET)); + new InputStreamReader(req.getInputStream(), UTF_8)); LfsRequest request = LfsGson.fromJson(r, LfsRequest.class); String path = req.getPathInfo(); diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java index 374a560581..b21c94e4e6 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java @@ -43,7 +43,7 @@ */ package org.eclipse.jgit.lfs.server.s3; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION; import java.io.UnsupportedEncodingException; @@ -359,13 +359,13 @@ class SignerV4 { private static byte[] hash(String s) { MessageDigest md = Constants.newMessageDigest(); - md.update(s.getBytes(CHARSET)); + md.update(s.getBytes(UTF_8)); return md.digest(); } private static byte[] sign(String stringData, byte[] key) { try { - byte[] data = stringData.getBytes(CHARSET); + byte[] data = stringData.getBytes(UTF_8); Mac mac = Mac.getInstance(HMACSHA256); mac.init(new SecretKeySpec(key, HMACSHA256)); return mac.doFinal(data); @@ -395,7 +395,7 @@ class SignerV4 { private static String urlEncode(String url, boolean keepPathSlash) { String encoded; try { - encoded = URLEncoder.encode(url, CHARSET.name()); + encoded = URLEncoder.encode(url, UTF_8.name()); } catch (UnsupportedEncodingException e) { throw new RuntimeException(LfsServerText.get().unsupportedUtf8, e); } diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF index d8376ced23..2a5b5a546a 100644 --- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF @@ -3,23 +3,23 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.lfs.test Bundle-SymbolicName: org.eclipse.jgit.lfs.test -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.junit;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk.filter;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", +Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.junit;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", org.hamcrest.core;version="[1.1.0,2.0.0)", org.junit;version="[4.12,5.0.0)", org.junit.runner;version="[4.12,5.0.0)", org.junit.runners;version="[4.12,5.0.0)" -Export-Package: org.eclipse.jgit.lfs.test;version="5.0.4";x-friends:="org.eclipse.jgit.lfs.server.test" +Export-Package: org.eclipse.jgit.lfs.test;version="5.1.3";x-friends:="org.eclipse.jgit.lfs.server.test" diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml index a55cecd4f7..5f00b1fa74 100644 --- a/org.eclipse.jgit.lfs.test/pom.xml +++ b/org.eclipse.jgit.lfs.test/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.test</artifactId> diff --git a/org.eclipse.jgit.lfs.test/src/org/eclipse/jgit/lfs/test/LongObjectIdTestUtils.java b/org.eclipse.jgit.lfs.test/src/org/eclipse/jgit/lfs/test/LongObjectIdTestUtils.java index e3c6ef80bc..c3c3859467 100644 --- a/org.eclipse.jgit.lfs.test/src/org/eclipse/jgit/lfs/test/LongObjectIdTestUtils.java +++ b/org.eclipse.jgit.lfs.test/src/org/eclipse/jgit/lfs/test/LongObjectIdTestUtils.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.lfs.test; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.BufferedInputStream; import java.io.FileNotFoundException; @@ -66,7 +66,7 @@ public class LongObjectIdTestUtils { */ public static LongObjectId hash(String s) { MessageDigest md = Constants.newMessageDigest(); - md.update(s.getBytes(CHARSET)); + md.update(s.getBytes(UTF_8)); return LongObjectId.fromRaw(md.digest()); } diff --git a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java index 8642e7eb3b..92a8176f57 100644 --- a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java +++ b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.lfs.lib; +import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.US_ASCII; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -62,7 +63,6 @@ import java.util.Locale; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException; import org.eclipse.jgit.lfs.test.LongObjectIdTestUtils; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.util.FileUtils; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -393,7 +393,7 @@ public class LongObjectIdTest { AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test"); ByteArrayOutputStream os = new ByteArrayOutputStream(64); try (OutputStreamWriter w = new OutputStreamWriter(os, - Constants.CHARSET)) { + UTF_8)) { id1.copyTo(w); } assertEquals(id1, LongObjectId.fromString(os.toByteArray(), 0)); @@ -404,7 +404,7 @@ public class LongObjectIdTest { AnyLongObjectId id1 = LongObjectIdTestUtils.hash("test"); ByteArrayOutputStream os = new ByteArrayOutputStream(64); try (OutputStreamWriter w = new OutputStreamWriter(os, - Constants.CHARSET)) { + UTF_8)) { char[] buf = new char[64]; id1.copyTo(buf, w); } diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.api.tools.prefs index 112e3c3187..c0030ded71 100644 --- a/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.api.tools.prefs +++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.pde.api.tools.prefs @@ -81,7 +81,7 @@ METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error -MISSING_EE_DESCRIPTIONS=Error +MISSING_EE_DESCRIPTIONS=Warning TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF index 3e1e2219b2..8785903456 100644 --- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF @@ -3,34 +3,33 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.lfs Bundle-SymbolicName: org.eclipse.jgit.lfs -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs;version="5.0.4", - org.eclipse.jgit.lfs.errors;version="5.0.4", - org.eclipse.jgit.lfs.internal;version="5.0.4";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server", - org.eclipse.jgit.lfs.lib;version="5.0.4" +Export-Package: org.eclipse.jgit.lfs;version="5.1.3", + org.eclipse.jgit.lfs.errors;version="5.1.3", + org.eclipse.jgit.lfs.internal;version="5.1.3";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server", + org.eclipse.jgit.lfs.lib;version="5.1.3" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: com.google.gson;version="[2.8.2,3.0.0)", com.google.gson.stream;version="[2.8.2,3.0.0)", org.apache.http.impl.client;version="[4.2.6,5.0.0)", org.apache.http.impl.conn;version="[4.2.6,5.0.0)", - org.eclipse.jgit.annotations;version="[5.0.4,5.1.0)";resolution:=optional, - org.eclipse.jgit.api.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.attributes;version="[5.0.4,5.1.0)", - org.eclipse.jgit.diff;version="[5.0.4,5.1.0)", - org.eclipse.jgit.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.hooks;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.pack;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.http;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk.filter;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util.io;version="[5.0.4,5.1.0)", - org.slf4j;version="[1.7.0,2.0.0)" + org.eclipse.jgit.annotations;version="[5.1.3,5.2.0)";resolution:=optional, + org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.attributes;version="[5.1.3,5.2.0)", + org.eclipse.jgit.diff;version="[5.1.3,5.2.0)", + org.eclipse.jgit.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.hooks;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.pack;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.http;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util.io;version="[5.1.3,5.2.0)" diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml index c231692738..d2ec285c9e 100644 --- a/org.eclipse.jgit.lfs/pom.xml +++ b/org.eclipse.jgit.lfs/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs</artifactId> diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java index 4f959409fc..0e3830c098 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.lfs; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.BufferedReader; import java.io.IOException; @@ -134,7 +134,7 @@ public class LfsPointer implements Comparable<LfsPointer> { */ public void encode(OutputStream out) { try (PrintStream ps = new PrintStream(out, false, - CHARSET.name())) { + UTF_8.name())) { ps.print("version "); //$NON-NLS-1$ ps.print(VERSION + "\n"); //$NON-NLS-1$ ps.print("oid " + HASH_FUNCTION_NAME + ":"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -143,7 +143,7 @@ public class LfsPointer implements Comparable<LfsPointer> { ps.print(size + "\n"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { // should not happen, we are using a standard charset - throw new UnsupportedCharsetException(CHARSET.name()); + throw new UnsupportedCharsetException(UTF_8.name()); } } @@ -165,7 +165,7 @@ public class LfsPointer implements Comparable<LfsPointer> { long sz = -1; try (BufferedReader br = new BufferedReader( - new InputStreamReader(in, CHARSET))) { + new InputStreamReader(in, UTF_8))) { for (String s = br.readLine(); s != null; s = br.readLine()) { if (s.startsWith("#") || s.length() == 0) { //$NON-NLS-1$ continue; diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java index de4449f5e3..3e6a26159b 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.lfs; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lfs.Protocol.OPERATION_UPLOAD; import static org.eclipse.jgit.lfs.internal.LfsConnectionFactory.toRequest; import static org.eclipse.jgit.transport.http.HttpConnection.HTTP_OK; @@ -201,14 +201,14 @@ public class LfsPrePushHook extends PrePushHook { private Map<String, LfsPointer> requestBatchUpload(HttpConnection api, Set<LfsPointer> toPush) throws IOException { - LfsPointer[] res = toPush.toArray(new LfsPointer[toPush.size()]); + LfsPointer[] res = toPush.toArray(new LfsPointer[0]); Map<String, LfsPointer> oidStr2ptr = new HashMap<>(); for (LfsPointer p : res) { oidStr2ptr.put(p.getOid().name(), p); } Gson gson = Protocol.gson(); api.getOutputStream().write( - gson.toJson(toRequest(OPERATION_UPLOAD, res)).getBytes(CHARSET)); + gson.toJson(toRequest(OPERATION_UPLOAD, res)).getBytes(UTF_8)); int responseCode = api.getResponseCode(); if (responseCode != HTTP_OK) { throw new IOException( @@ -221,7 +221,7 @@ public class LfsPrePushHook extends PrePushHook { private void uploadContents(HttpConnection api, Map<String, LfsPointer> oid2ptr) throws IOException { try (JsonReader reader = new JsonReader( - new InputStreamReader(api.getInputStream()))) { + new InputStreamReader(api.getInputStream(), UTF_8))) { for (Protocol.ObjectInfo o : parseObjects(reader)) { if (o.actions == null) { continue; diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java index 6bff12f9cc..fac87c177e 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.lfs; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.io.InputStream; @@ -170,7 +170,7 @@ public class SmudgeFilter extends FilterCommand { .write(gson .toJson(LfsConnectionFactory .toRequest(Protocol.OPERATION_DOWNLOAD, res)) - .getBytes(CHARSET)); + .getBytes(UTF_8)); int responseCode = lfsServerConn.getResponseCode(); if (responseCode != HttpConnection.HTTP_OK) { throw new IOException( @@ -179,7 +179,8 @@ public class SmudgeFilter extends FilterCommand { Integer.valueOf(responseCode))); } try (JsonReader reader = new JsonReader( - new InputStreamReader(lfsServerConn.getInputStream()))) { + new InputStreamReader(lfsServerConn.getInputStream(), + UTF_8))) { Protocol.Response resp = gson.fromJson(reader, Protocol.Response.class); for (Protocol.ObjectInfo o : resp.objects) { diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml index d09852bcd2..f95bad6c61 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit" label="%featureName" - version="5.0.4.qualifier" + version="5.1.3.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml index a9a58affb7..8571e8ce54 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml index 485fd6ba83..4829918193 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit.http.apache" label="%featureName" - version="5.0.4.qualifier" + version="5.1.3.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml index d148ac34c8..3872c46361 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml index 6551330d57..99ebd30a4e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit.junit" label="%featureName" - version="5.0.4.qualifier" + version="5.1.3.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml index f65326ea66..c19f0799e4 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml index 72e15da908..92bacfe97e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit.lfs" label="%featureName" - version="5.0.4.qualifier" + version="5.1.3.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml index 35a4fda51e..d6e96b3330 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml index 18a7d1a084..e43008cf08 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit.pgm" label="%featureName" - version="5.0.4.qualifier" + version="5.1.3.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> @@ -31,8 +31,8 @@ version="0.0.0"/> <requires> - <import feature="org.eclipse.jgit" version="5.0.4" match="equivalent"/> - <import feature="org.eclipse.jgit.lfs" version="5.0.4" match="equivalent"/> + <import feature="org.eclipse.jgit" version="5.1.3" match="equivalent"/> + <import feature="org.eclipse.jgit.lfs" version="5.1.3" match="equivalent"/> </requires> <plugin diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml index 73a7d3f13a..cf4ff9d58d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml index 810d018d25..b3e587657f 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit.pgm.source" label="%featureName" - version="5.0.4.qualifier" + version="5.1.3.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml index 88b8ce9c1f..f83679021b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml index c8c3b51eeb..4e91331ad9 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.repository</artifactId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml index 12d6fe3160..0789a8fa83 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit.source" label="%featureName" - version="5.0.4.qualifier" + version="5.1.3.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml index 7c832411c5..643297ea9d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF index fc7dfa6230..d0c1cdcf2b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF @@ -2,4 +2,4 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: JGit Target Platform Bundle Bundle-SymbolicName: org.eclipse.jgit.target -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target index dfb5a8f442..28ebdbf703 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target @@ -1,40 +1,40 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.5" sequenceNumber="1535179254"> +<target name="jgit-4.5" sequenceNumber="1536523000"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.http" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.io" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.security" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.server" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.util" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.8.v20171121"/> - <repository id="jetty-9.4.8" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.8.v20171121"/> + <unit id="org.eclipse.jetty.client" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.11.v20180605"/> + <repository id="jetty-9.4.11" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.11.v20180605"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.apache.ant" version="1.9.6.v201510161327"/> <unit id="org.apache.ant.source" version="1.9.6.v201510161327"/> - <unit id="org.apache.commons.codec" version="1.9.0.v20170208-1614"/> - <unit id="org.apache.commons.codec.source" version="1.9.0.v20170208-1614"/> + <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> + <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.15.0.v20180119-1613"/> <unit id="org.apache.commons.compress.source" version="1.15.0.v20180119-1613"/> - <unit id="org.apache.commons.logging" version="1.1.1.v201101211721"/> - <unit id="org.apache.commons.logging.source" version="1.1.1.v201101211721"/> - <unit id="org.apache.httpcomponents.httpcore" version="4.4.6.v20170210-0925"/> - <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.6.v20170210-0925"/> - <unit id="org.apache.httpcomponents.httpclient" version="4.5.2.v20180410-1551"/> - <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.2.v20180410-1551"/> + <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.httpcomponents.httpclient" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore" version="4.4.9.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.9.v20180409-1525"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> @@ -66,7 +66,7 @@ <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/> <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180606145124/repository"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/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.5.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd index c85343c9f9..8e65c9820e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd @@ -1,7 +1,7 @@ target "jgit-4.5" with source configurePhase -include "projects/jetty-9.4.8.tpd" -include "orbit/R20180606145124-Photon.tpd" +include "projects/jetty-9.4.11.tpd" +include "orbit/R20180905201904-2018-09.tpd" location "http://download.eclipse.org/releases/mars/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target index dbfd694b24..8490e55b27 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target @@ -1,40 +1,40 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.6" sequenceNumber="1535179241"> +<target name="jgit-4.6" sequenceNumber="1536522989"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.http" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.io" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.security" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.server" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.util" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.8.v20171121"/> - <repository id="jetty-9.4.8" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.8.v20171121"/> + <unit id="org.eclipse.jetty.client" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.11.v20180605"/> + <repository id="jetty-9.4.11" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.11.v20180605"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.apache.ant" version="1.9.6.v201510161327"/> <unit id="org.apache.ant.source" version="1.9.6.v201510161327"/> - <unit id="org.apache.commons.codec" version="1.9.0.v20170208-1614"/> - <unit id="org.apache.commons.codec.source" version="1.9.0.v20170208-1614"/> + <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> + <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.15.0.v20180119-1613"/> <unit id="org.apache.commons.compress.source" version="1.15.0.v20180119-1613"/> - <unit id="org.apache.commons.logging" version="1.1.1.v201101211721"/> - <unit id="org.apache.commons.logging.source" version="1.1.1.v201101211721"/> - <unit id="org.apache.httpcomponents.httpcore" version="4.4.6.v20170210-0925"/> - <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.6.v20170210-0925"/> - <unit id="org.apache.httpcomponents.httpclient" version="4.5.2.v20180410-1551"/> - <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.2.v20180410-1551"/> + <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.httpcomponents.httpclient" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore" version="4.4.9.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.9.v20180409-1525"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> @@ -66,7 +66,7 @@ <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/> <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180606145124/repository"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/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.6.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd index 3c2a910f8d..44c846e0bf 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd @@ -1,7 +1,7 @@ target "jgit-4.6" with source configurePhase -include "projects/jetty-9.4.8.tpd" -include "orbit/R20180606145124-Photon.tpd" +include "projects/jetty-9.4.11.tpd" +include "orbit/R20180905201904-2018-09.tpd" location "http://download.eclipse.org/releases/neon/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target index be7719d88f..a6651b837b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target @@ -1,40 +1,40 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.7" sequenceNumber="1535179221"> +<target name="jgit-4.7" sequenceNumber="1536522970"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.http" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.io" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.security" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.server" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.util" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.8.v20171121"/> - <repository id="jetty-9.4.8" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.8.v20171121"/> + <unit id="org.eclipse.jetty.client" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.11.v20180605"/> + <repository id="jetty-9.4.11" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.11.v20180605"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.apache.ant" version="1.9.6.v201510161327"/> <unit id="org.apache.ant.source" version="1.9.6.v201510161327"/> - <unit id="org.apache.commons.codec" version="1.9.0.v20170208-1614"/> - <unit id="org.apache.commons.codec.source" version="1.9.0.v20170208-1614"/> + <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> + <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.15.0.v20180119-1613"/> <unit id="org.apache.commons.compress.source" version="1.15.0.v20180119-1613"/> - <unit id="org.apache.commons.logging" version="1.1.1.v201101211721"/> - <unit id="org.apache.commons.logging.source" version="1.1.1.v201101211721"/> - <unit id="org.apache.httpcomponents.httpcore" version="4.4.6.v20170210-0925"/> - <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.6.v20170210-0925"/> - <unit id="org.apache.httpcomponents.httpclient" version="4.5.2.v20180410-1551"/> - <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.2.v20180410-1551"/> + <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.httpcomponents.httpclient" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore" version="4.4.9.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.9.v20180409-1525"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> @@ -66,7 +66,7 @@ <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/> <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180606145124/repository"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/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.7.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd index 4e543fffee..b63955f2af 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd @@ -1,7 +1,7 @@ target "jgit-4.7" with source configurePhase -include "projects/jetty-9.4.8.tpd" -include "orbit/R20180606145124-Photon.tpd" +include "projects/jetty-9.4.11.tpd" +include "orbit/R20180905201904-2018-09.tpd" location "http://download.eclipse.org/releases/oxygen/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target index 3de172b822..7adb7dafd6 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target @@ -1,40 +1,40 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.8" sequenceNumber="1535179205"> +<target name="jgit-4.8" sequenceNumber="1536522959"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.http" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.io" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.security" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.server" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.util" version="9.4.8.v20171121"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.8.v20171121"/> - <repository id="jetty-9.4.8" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.8.v20171121"/> + <unit id="org.eclipse.jetty.client" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.11.v20180605"/> + <repository id="jetty-9.4.11" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.11.v20180605"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.apache.ant" version="1.9.6.v201510161327"/> <unit id="org.apache.ant.source" version="1.9.6.v201510161327"/> - <unit id="org.apache.commons.codec" version="1.9.0.v20170208-1614"/> - <unit id="org.apache.commons.codec.source" version="1.9.0.v20170208-1614"/> + <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> + <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.15.0.v20180119-1613"/> <unit id="org.apache.commons.compress.source" version="1.15.0.v20180119-1613"/> - <unit id="org.apache.commons.logging" version="1.1.1.v201101211721"/> - <unit id="org.apache.commons.logging.source" version="1.1.1.v201101211721"/> - <unit id="org.apache.httpcomponents.httpcore" version="4.4.6.v20170210-0925"/> - <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.6.v20170210-0925"/> - <unit id="org.apache.httpcomponents.httpclient" version="4.5.2.v20180410-1551"/> - <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.2.v20180410-1551"/> + <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.httpcomponents.httpclient" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore" version="4.4.9.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.9.v20180409-1525"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> @@ -66,7 +66,7 @@ <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/> <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180606145124/repository"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/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.8.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd index 0ea2b99f32..4e41ad9a04 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd @@ -1,7 +1,7 @@ target "jgit-4.8" with source configurePhase -include "projects/jetty-9.4.8.tpd" -include "orbit/R20180606145124-Photon.tpd" +include "projects/jetty-9.4.11.tpd" +include "orbit/R20180905201904-2018-09.tpd" location "http://download.eclipse.org/releases/photon/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9-staging.target new file mode 100644 index 0000000000..bdabdffa28 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9-staging.target @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?pde?> +<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> +<target name="jgit-4.9-staging" sequenceNumber="1536522948"> + <locations> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="org.eclipse.jetty.client" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util" version="9.4.11.v20180605"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.11.v20180605"/> + <repository id="jetty-9.4.11" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.11.v20180605"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="org.apache.ant" version="1.9.6.v201510161327"/> + <unit id="org.apache.ant.source" version="1.9.6.v201510161327"/> + <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> + <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> + <unit id="org.apache.commons.compress" version="1.15.0.v20180119-1613"/> + <unit id="org.apache.commons.compress.source" version="1.15.0.v20180119-1613"/> + <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.httpcomponents.httpclient" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.5.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore" version="4.4.9.v20180409-1525"/> + <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.9.v20180409-1525"/> + <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> + <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> + <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.hamcrest" version="1.1.0.v20090501071000"/> + <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> + <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/> + <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/> + <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/> + <unit id="javaewah" version="1.1.6.v20160919-1400"/> + <unit id="javaewah.source" version="1.1.6.v20160919-1400"/> + <unit id="org.objenesis" version="1.0.0.v201505121915"/> + <unit id="org.objenesis.source" version="1.0.0.v201505121915"/> + <unit id="org.mockito" version="1.8.4.v201303031500"/> + <unit id="org.mockito.source" version="1.8.4.v201303031500"/> + <unit id="com.google.gson" version="2.8.2.v20180104-1110"/> + <unit id="com.google.gson.source" version="2.8.2.v20180104-1110"/> + <unit id="com.jcraft.jsch" version="0.1.54.v20170116-1932"/> + <unit id="com.jcraft.jsch.source" version="0.1.54.v20170116-1932"/> + <unit id="org.junit" version="4.12.0.v201504281640"/> + <unit id="org.junit.source" version="4.12.0.v201504281640"/> + <unit id="javax.servlet" version="3.1.0.v201410161800"/> + <unit id="javax.servlet.source" version="3.1.0.v201410161800"/> + <unit id="org.tukaani.xz" version="1.6.0.v20170629-1752"/> + <unit id="org.tukaani.xz.source" version="1.6.0.v20170629-1752"/> + <unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/> + <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/> + <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/> + <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> + <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/> + <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/repository"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="org.eclipse.osgi" version="0.0.0"/> + <repository location="http://download.eclipse.org/staging/2018-09/"/> + </location> + </locations> +</target> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9-staging.tpd new file mode 100644 index 0000000000..6f963c7ceb --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9-staging.tpd @@ -0,0 +1,8 @@ +target "jgit-4.9-staging" with source configurePhase + +include "projects/jetty-9.4.11.tpd" +include "orbit/R20180905201904-2018-09.tpd" + +location "http://download.eclipse.org/staging/2018-09/" { + org.eclipse.osgi lazy +}
\ No newline at end of file diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180905201904-2018-09.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180905201904-2018-09.tpd new file mode 100644 index 0000000000..eaae99cbe9 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180905201904-2018-09.tpd @@ -0,0 +1,48 @@ +target "R20180905201904-2018-09" with source configurePhase +// see http://download.eclipse.org/tools/orbit/downloads/ + +location "http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/repository" { + org.apache.ant [1.9.6.v201510161327,1.9.6.v201510161327] + org.apache.ant.source [1.9.6.v201510161327,1.9.6.v201510161327] + org.apache.commons.codec [1.10.0.v20180409-1845,1.10.0.v20180409-1845] + org.apache.commons.codec.source [1.10.0.v20180409-1845,1.10.0.v20180409-1845] + org.apache.commons.compress [1.15.0.v20180119-1613,1.15.0.v20180119-1613] + org.apache.commons.compress.source [1.15.0.v20180119-1613,1.15.0.v20180119-1613s] + org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502] + org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502] + org.apache.httpcomponents.httpclient [4.5.5.v20180409-1525,4.5.5.v20180409-1525] + org.apache.httpcomponents.httpclient.source [4.5.5.v20180409-1525,4.5.5.v20180409-1525] + org.apache.httpcomponents.httpcore [4.4.9.v20180409-1525,4.4.9.v20180409-1525] + org.apache.httpcomponents.httpcore.source [4.4.9.v20180409-1525,4.4.9.v20180409-1525] + org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815] + org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815] + 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.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000] + org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519] + org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519] + org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246] + org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246] + javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400] + javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400] + org.objenesis [1.0.0.v201505121915,1.0.0.v201505121915] + org.objenesis.source [1.0.0.v201505121915,1.0.0.v201505121915] + org.mockito [1.8.4.v201303031500,1.8.4.v201303031500] + org.mockito.source [1.8.4.v201303031500,1.8.4.v201303031500] + com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110] + com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110] + com.jcraft.jsch [0.1.54.v20170116-1932,0.1.54.v20170116-1932] + com.jcraft.jsch.source [0.1.54.v20170116-1932,0.1.54.v20170116-1932] + org.junit [4.12.0.v201504281640,4.12.0.v201504281640] + org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640] + javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800] + javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800] + org.tukaani.xz [1.6.0.v20170629-1752,1.6.0.v20170629-1752] + org.tukaani.xz.source [1.6.0.v20170629-1752,1.6.0.v20170629-1752] + org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250] + org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250] + org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200] + org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200] + com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305] + com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305] +} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml index 3c60a8376e..f5b0078c77 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml @@ -49,7 +49,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.target</artifactId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.11.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.11.tpd new file mode 100644 index 0000000000..d2fd9017b3 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.11.tpd @@ -0,0 +1,20 @@ +target "jetty-9.4.11" with source configurePhase + +location jetty-9.4.11 "http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.11.v20180605" { + org.eclipse.jetty.client [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.client.source [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.continuation [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.continuation.source [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.http [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.http.source [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.io [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.io.source [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.security [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.security.source [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.server [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.server.source [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.servlet [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.servlet.source [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.util [9.4.11.v20180605,9.4.11.v20180605] + org.eclipse.jetty.util.source [9.4.11.v20180605,9.4.11.v20180605] +} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.8.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.8.tpd deleted file mode 100644 index e37a062115..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.8.tpd +++ /dev/null @@ -1,20 +0,0 @@ -target "jetty-9.4.8" with source configurePhase - -location jetty-9.4.8 "http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.8.v20171121" { - org.eclipse.jetty.client [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.client.source [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.continuation [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.continuation.source [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.http [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.http.source [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.io [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.io.source [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.security [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.security.source [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.server [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.server.source [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.servlet [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.servlet.source [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.util [9.4.8.v20171121,9.4.8.v20171121] - org.eclipse.jetty.util.source [9.4.8.v20171121,9.4.8.v20171121] -} diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 3cb21c1eb1..142a70639d 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -53,13 +53,13 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> <packaging>pom</packaging> <name>JGit Tycho Parent</name> <properties> - <tycho-version>1.1.0</tycho-version> + <tycho-version>1.2.0</tycho-version> <tycho-extras-version>${tycho-version}</tycho-extras-version> <target-platform>jgit-4.6</target-platform> </properties> @@ -169,7 +169,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> - <version>3.0.2</version> + <version>3.1.0</version> <configuration> <encoding>ISO-8859-1</encoding> </configuration> @@ -236,12 +236,12 @@ <plugin> <groupId>org.eclipse.cbi.maven.plugins</groupId> <artifactId>eclipse-jarsigner-plugin</artifactId> - <version>1.1.4</version> + <version>1.1.5</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> - <version>1.12</version> + <version>3.0.0</version> </plugin> </plugins> </pluginManagement> diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF index 39910ce86e..49c0e58093 100644 --- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF @@ -3,28 +3,28 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.pgm.test Bundle-SymbolicName: org.eclipse.jgit.pgm.test -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.api;version="[5.0.4,5.1.0)", - org.eclipse.jgit.api.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.diff;version="[5.0.4,5.1.0)", - org.eclipse.jgit.dircache;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="5.0.4", - org.eclipse.jgit.junit;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.merge;version="[5.0.4,5.1.0)", - org.eclipse.jgit.pgm;version="[5.0.4,5.1.0)", - org.eclipse.jgit.pgm.internal;version="[5.0.4,5.1.0)", - org.eclipse.jgit.pgm.opt;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util.io;version="[5.0.4,5.1.0)", +Import-Package: org.eclipse.jgit.api;version="[5.1.3,5.2.0)", + org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.diff;version="[5.1.3,5.2.0)", + org.eclipse.jgit.dircache;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="5.1.3", + org.eclipse.jgit.junit;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.merge;version="[5.1.3,5.2.0)", + org.eclipse.jgit.pgm;version="[5.1.3,5.2.0)", + org.eclipse.jgit.pgm.internal;version="[5.1.3,5.2.0)", + org.eclipse.jgit.pgm.opt;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util.io;version="[5.1.3,5.2.0)", org.hamcrest.core;bundle-version="[1.1.0,2.0.0)", org.junit;version="[4.12,5.0.0)", org.junit.rules;version="[4.12,5.0.0)", diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml index 30c32ed698..25c7962326 100644 --- a/org.eclipse.jgit.pgm.test/pom.xml +++ b/org.eclipse.jgit.pgm.test/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.pgm.test</artifactId> diff --git a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/pgm/CLIGitCommand.java b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/pgm/CLIGitCommand.java index 44ad79defc..81875f11bc 100644 --- a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/pgm/CLIGitCommand.java +++ b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/pgm/CLIGitCommand.java @@ -230,7 +230,7 @@ public class CLIGitCommand extends Main { } if (r.length() > 0) list.add(r.toString()); - return list.toArray(new String[list.size()]); + return list.toArray(new String[0]); } public static class Result { diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java index afeb5ef6e4..47eb156c55 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.pgm; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -544,7 +544,7 @@ public class ArchiveTest extends CLIRepositoryTestCase { byte[] result = CLIGitCommand.executeRaw( "git archive --format=zip HEAD", db).outBytes(); - assertArrayEquals(l.toArray(new String[l.size()]), + assertArrayEquals(l.toArray(new String[0]), listZipEntries(result)); } @@ -564,7 +564,7 @@ public class ArchiveTest extends CLIRepositoryTestCase { byte[] result = CLIGitCommand.executeRaw( "git archive --format=tar HEAD", db).outBytes(); - assertArrayEquals(l.toArray(new String[l.size()]), + assertArrayEquals(l.toArray(new String[0]), listTarEntries(result)); } @@ -612,7 +612,7 @@ public class ArchiveTest extends CLIRepositoryTestCase { private BufferedReader readFromProcess(Process proc) throws Exception { return new BufferedReader( - new InputStreamReader(proc.getInputStream(), CHARSET)); + new InputStreamReader(proc.getInputStream(), UTF_8)); } private void grepForEntry(String name, String mode, String... cmdline) @@ -697,7 +697,7 @@ public class ArchiveTest extends CLIRepositoryTestCase { while ((e = in.getNextEntry()) != null) l.add(e.getName()); } - return l.toArray(new String[l.size()]); + return l.toArray(new String[0]); } private static Future<Object> writeAsync(OutputStream stream, byte[] data) { @@ -730,7 +730,7 @@ public class ArchiveTest extends CLIRepositoryTestCase { while ((line = reader.readLine()) != null) l.add(line); - return l.toArray(new String[l.size()]); + return l.toArray(new String[0]); } finally { writing.get(); proc.destroy(); @@ -750,11 +750,11 @@ public class ArchiveTest extends CLIRepositoryTestCase { // found! List<String> l = new ArrayList<>(); BufferedReader reader = new BufferedReader( - new InputStreamReader(in, CHARSET)); + new InputStreamReader(in, UTF_8)); String line; while ((line = reader.readLine()) != null) l.add(line); - return l.toArray(new String[l.size()]); + return l.toArray(new String[0]); } // not found @@ -774,7 +774,7 @@ public class ArchiveTest extends CLIRepositoryTestCase { while ((line = reader.readLine()) != null) l.add(line); - return l.toArray(new String[l.size()]); + return l.toArray(new String[0]); } finally { writing.get(); proc.destroy(); diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsFilesTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsFilesTest.java new file mode 100644 index 0000000000..d2902061a4 --- /dev/null +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsFilesTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2017, Matthias Sohn <matthias.sohn@sap.com> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.pgm; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.junit.JGitTestUtil; +import org.eclipse.jgit.lib.CLIRepositoryTestCase; +import org.eclipse.jgit.util.FileUtils; +import org.junit.Before; +import org.junit.Test; + +public class LsFilesTest extends CLIRepositoryTestCase { + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + try (Git git = new Git(db)) { + JGitTestUtil.writeTrashFile(db, "hello", "hello"); + JGitTestUtil.writeTrashFile(db, "dir", "world", "world"); + git.add().addFilepattern("dir").call(); + git.commit().setMessage("Initial commit").call(); + + JGitTestUtil.writeTrashFile(db, "hello2", "hello"); + git.add().addFilepattern("hello2").call(); + FileUtils.createSymLink(new File(db.getWorkTree(), "link"), + "target"); + FileUtils.mkdir(new File(db.getWorkTree(), "target")); + writeTrashFile("target/file", "someData"); + git.add().addFilepattern("target").addFilepattern("link").call(); + git.commit().setMessage("hello2").call(); + + JGitTestUtil.writeTrashFile(db, "staged", "x"); + JGitTestUtil.deleteTrashFile(db, "hello2"); + git.add().addFilepattern("staged").call(); + JGitTestUtil.writeTrashFile(db, "untracked", "untracked"); + } + } + + @Test + public void testHelp() throws Exception { + String[] result = execute("git ls-files -h"); + assertTrue(result[1].startsWith("jgit ls-files")); + } + + @Test + public void testLsFiles() throws Exception { + assertArrayEquals(new String[] { "dir/world", "hello2", "link", + "staged", "target/file", "" }, execute("git ls-files")); + } +} diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index f8aa095562..abe59f46aa 100644 --- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.pgm Bundle-SymbolicName: org.eclipse.jgit.pgm -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-Localization: plugin @@ -28,49 +28,49 @@ Import-Package: javax.servlet;version="[3.1.0,4.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.jgit.api;version="[5.0.4,5.1.0)", - org.eclipse.jgit.api.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.archive;version="[5.0.4,5.1.0)", - org.eclipse.jgit.awtui;version="[5.0.4,5.1.0)", - org.eclipse.jgit.blame;version="[5.0.4,5.1.0)", - org.eclipse.jgit.diff;version="[5.0.4,5.1.0)", - org.eclipse.jgit.dircache;version="[5.0.4,5.1.0)", - org.eclipse.jgit.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.gitrepo;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.ketch;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.io;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.pack;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.reftable;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.reftree;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.server;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.server.fs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs.server.s3;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.merge;version="[5.0.4,5.1.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.notes;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revplot;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk.filter;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.pack;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.http.apache;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.resolver;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk.filter;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util.io;version="[5.0.4,5.1.0)", + org.eclipse.jgit.api;version="[5.1.3,5.2.0)", + org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.archive;version="[5.1.3,5.2.0)", + org.eclipse.jgit.awtui;version="[5.1.3,5.2.0)", + org.eclipse.jgit.blame;version="[5.1.3,5.2.0)", + org.eclipse.jgit.diff;version="[5.1.3,5.2.0)", + org.eclipse.jgit.dircache;version="[5.1.3,5.2.0)", + org.eclipse.jgit.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.gitrepo;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.ketch;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.io;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.pack;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.reftable;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.reftree;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.server;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.server.fs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs.server.s3;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.merge;version="[5.1.3,5.2.0)", + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.notes;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revplot;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk.filter;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.pack;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.http.apache;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.resolver;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util.io;version="[5.1.3,5.2.0)", org.kohsuke.args4j;version="[2.33.0,3.0.0)", org.kohsuke.args4j.spi;version="[2.33.0,3.0.0)" -Export-Package: org.eclipse.jgit.console;version="5.0.4"; +Export-Package: org.eclipse.jgit.console;version="5.1.3"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util", - org.eclipse.jgit.pgm;version="5.0.4"; + org.eclipse.jgit.pgm;version="5.1.3"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.pgm.opt, @@ -81,11 +81,11 @@ Export-Package: org.eclipse.jgit.console;version="5.0.4"; org.eclipse.jgit.treewalk, javax.swing, org.eclipse.jgit.transport", - org.eclipse.jgit.pgm.debug;version="5.0.4"; + org.eclipse.jgit.pgm.debug;version="5.1.3"; uses:="org.eclipse.jgit.util.io, org.eclipse.jgit.pgm", - org.eclipse.jgit.pgm.internal;version="5.0.4";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", - org.eclipse.jgit.pgm.opt;version="5.0.4"; + org.eclipse.jgit.pgm.internal;version="5.1.3";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", + org.eclipse.jgit.pgm.opt;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.kohsuke.args4j.spi, diff --git a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF index 1d4575ef88..e550903184 100644 --- a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF @@ -3,5 +3,5 @@ Bundle-ManifestVersion: 2 Bundle-Name: org.eclipse.jgit.pgm - Sources Bundle-SymbolicName: org.eclipse.jgit.pgm.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 5.0.4.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.0.4.qualifier";roots="." +Bundle-Version: 5.1.3.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.1.3.qualifier";roots="." diff --git a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin index 902547305d..39fbe2ed75 100644 --- a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin +++ b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin @@ -18,6 +18,7 @@ org.eclipse.jgit.pgm.Glog org.eclipse.jgit.pgm.IndexPack org.eclipse.jgit.pgm.Init org.eclipse.jgit.pgm.Log +org.eclipse.jgit.pgm.LsFiles org.eclipse.jgit.pgm.LsRemote org.eclipse.jgit.pgm.LsTree org.eclipse.jgit.pgm.Merge diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml index db6745e2d0..4d5792913e 100644 --- a/org.eclipse.jgit.pgm/pom.xml +++ b/org.eclipse.jgit.pgm/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.pgm</artifactId> @@ -108,19 +108,16 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>${slf4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> - <version>${slf4j-version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> - <version>${log4j-version}</version> </dependency> <dependency> diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties index e9370930d1..8ff9c6bb10 100644 --- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties +++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties @@ -245,6 +245,7 @@ usage_LFSPort=Server http port usage_LFSRunStore=Store (fs | s3), store lfs objects in file system or Amazon S3 usage_LFSStoreUrl=URL of the LFS store usage_LongFormat=Always output the long format +usage_LsFiles=Show information about files in the index and the working tree usage_LsRemote=List references in a remote repository usage_lsRemoteHeads=Show only refs starting with refs/heads usage_lsRemoteTags=Show only refs starting with refs/tags diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java index 5754d7c44f..dbdccc10e2 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.pgm; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.BufferedReader; import java.io.IOException; @@ -114,7 +114,7 @@ public class CommandCatalog { } private static CommandRef[] toSortedArray(Collection<CommandRef> c) { - final CommandRef[] r = c.toArray(new CommandRef[c.size()]); + final CommandRef[] r = c.toArray(new CommandRef[0]); Arrays.sort(r, new Comparator<CommandRef>() { @Override public int compare(CommandRef o1, CommandRef o2) { @@ -148,7 +148,7 @@ public class CommandCatalog { private void scan(URL cUrl) { try (BufferedReader cIn = new BufferedReader( - new InputStreamReader(cUrl.openStream(), CHARSET))) { + new InputStreamReader(cUrl.openStream(), UTF_8))) { String line; while ((line = cIn.readLine()) != null) { if (line.length() > 0 && !line.startsWith("#")) //$NON-NLS-1$ diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java index f9c1cf5d38..f91474859d 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java @@ -73,7 +73,7 @@ class Describe extends TextBuiltin { if (tree != null) cmd.setTarget(tree); cmd.setLong(longDesc); - cmd.setMatch(patterns.toArray(new String[patterns.size()])); + cmd.setMatch(patterns.toArray(new String[0])); String result = null; try { result = cmd.call(); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java new file mode 100644 index 0000000000..dc13000d63 --- /dev/null +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2017, Matthias Sohn <matthias.sohn@sap.com> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.pgm; + +import static java.util.function.Predicate.isEqual; +import static org.eclipse.jgit.lib.FileMode.EXECUTABLE_FILE; +import static org.eclipse.jgit.lib.FileMode.GITLINK; +import static org.eclipse.jgit.lib.FileMode.REGULAR_FILE; +import static org.eclipse.jgit.lib.FileMode.SYMLINK; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jgit.dircache.DirCacheIterator; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.treewalk.CanonicalTreeParser; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; +import org.eclipse.jgit.util.QuotedString; +import org.kohsuke.args4j.Option; +import org.kohsuke.args4j.spi.StopOptionHandler; + +@Command(common = true, usage = "usage_LsFiles") +class LsFiles extends TextBuiltin { + + @Option(name = "--", metaVar = "metaVar_paths", handler = StopOptionHandler.class) + private List<String> paths = new ArrayList<>(); + + @Override + protected void run() throws Exception { + try (RevWalk rw = new RevWalk(db); + TreeWalk tw = new TreeWalk(db)) { + final ObjectId head = db.resolve(Constants.HEAD); + if (head == null) { + return; + } + RevCommit c = rw.parseCommit(head); + CanonicalTreeParser p = new CanonicalTreeParser(); + p.reset(rw.getObjectReader(), c.getTree()); + tw.reset(); // drop the first empty tree, which we do not need here + if (paths.size() > 0) { + tw.setFilter(PathFilterGroup.createFromStrings(paths)); + } + tw.addTree(p); + tw.addTree(new DirCacheIterator(db.readDirCache())); + tw.setRecursive(true); + while (tw.next()) { + if (filterFileMode(tw, EXECUTABLE_FILE, GITLINK, REGULAR_FILE, + SYMLINK)) { + outw.println( + QuotedString.GIT_PATH.quote(tw.getPathString())); + } + } + } + } + + private boolean filterFileMode(TreeWalk tw, FileMode... modes) { + return Arrays.stream(modes).anyMatch(isEqual(tw.getFileMode(0)) + .or(isEqual(tw.getFileMode(1)))); + } +} diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java index ac53de9767..ad10ec9e44 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.pgm; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.File; import java.io.IOException; @@ -71,7 +71,6 @@ import org.eclipse.jgit.lib.RepositoryBuilder; import org.eclipse.jgit.pgm.internal.CLIText; import org.eclipse.jgit.pgm.opt.CmdLineParser; import org.eclipse.jgit.pgm.opt.SubcommandHandler; -import org.eclipse.jgit.storage.file.WindowCacheConfig; import org.eclipse.jgit.transport.HttpTransport; import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory; import org.eclipse.jgit.util.CachedAuthenticator; @@ -106,19 +105,10 @@ public class Main { private ExecutorService gcExecutor; - private static final int MB = 1024 * 1024; - /** * <p>Constructor for Main.</p> */ public Main() { - final WindowCacheConfig c = new WindowCacheConfig(); - c.setPackedGitMMAP(true); - c.setPackedGitWindowSize(8 * 1024); - c.setPackedGitLimit(10 * MB); - c.setDeltaBaseCacheLimit(10 * MB); - c.setStreamFileThreshold(50 * MB); - c.install(); HttpTransport.setConnectionFactory(new HttpClientConnectionFactory()); BuiltinLFS.register(); gcExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() { @@ -227,7 +217,7 @@ public class Main { } PrintWriter createErrorWriter() { - return new PrintWriter(new OutputStreamWriter(System.err, CHARSET)); + return new PrintWriter(new OutputStreamWriter(System.err, UTF_8)); } private void execute(String[] argv) throws Exception { @@ -285,7 +275,7 @@ public class Main { final TextBuiltin cmd = subcommand; init(cmd); try { - cmd.execute(arguments.toArray(new String[arguments.size()])); + cmd.execute(arguments.toArray(new String[0])); } finally { if (cmd.outw != null) { cmd.outw.flush(); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java index 3308e18f24..63eba15abc 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java @@ -130,7 +130,7 @@ class Remote extends TextBuiltin { fetchArgs.add(name); } - fetch.execute(fetchArgs.toArray(new String[fetchArgs.size()])); + fetch.execute(fetchArgs.toArray(new String[0])); // flush the streams fetch.outw.flush(); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java index 575a122158..248eaac8ad 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.pgm.debug; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.HEAD; import static org.eclipse.jgit.lib.Constants.MASTER; import static org.eclipse.jgit.lib.Constants.R_HEADS; @@ -154,7 +154,7 @@ class BenchmarkReftable extends TextBuiltin { throws IOException, FileNotFoundException { RefList.Builder<Ref> list = new RefList.Builder<>(); try (BufferedReader br = new BufferedReader(new InputStreamReader( - new FileInputStream(lsRemotePath), CHARSET))) { + new FileInputStream(lsRemotePath), UTF_8))) { Ref last = null; String line; while ((line = br.readLine()) != null) { diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java index fda19017d2..0b36e9ca61 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java @@ -70,7 +70,7 @@ class ReadReftable extends TextBuiltin { BlockSource src = BlockSource.from(in); ReftableReader reader = new ReftableReader(src)) { try (RefCursor rc = ref != null - ? reader.seekRef(ref) + ? reader.seekRefsWithPrefix(ref) : reader.allRefs()) { while (rc.next()) { write(rc.getRef()); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java index 2d16fefa71..8948c27537 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java @@ -43,6 +43,8 @@ package org.eclipse.jgit.pgm.debug; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -141,7 +143,7 @@ class RebuildCommitGraph extends TextBuiltin { try (RevWalk rw = new RevWalk(db); final BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(graph), - Constants.CHARSET))) { + UTF_8))) { String line; while ((line = br.readLine()) != null) { final String[] parts = line.split("[ \t]{1,}"); //$NON-NLS-1$ @@ -280,7 +282,7 @@ class RebuildCommitGraph extends TextBuiltin { try (RevWalk rw = new RevWalk(db); BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(refList), - Constants.CHARSET))) { + UTF_8))) { String line; while ((line = br.readLine()) != null) { final String[] parts = line.split("[ \t]{1,}"); //$NON-NLS-1$ diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java index c5ea028be8..6cbc1b082b 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.pgm.debug; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.HEAD; import static org.eclipse.jgit.lib.Constants.MASTER; import static org.eclipse.jgit.lib.Constants.R_HEADS; @@ -192,7 +192,7 @@ class WriteReftable extends TextBuiltin { static List<Ref> readRefs(String inputFile) throws IOException { List<Ref> refs = new ArrayList<>(); try (BufferedReader br = new BufferedReader( - new InputStreamReader(new FileInputStream(inputFile), CHARSET))) { + new InputStreamReader(new FileInputStream(inputFile), UTF_8))) { String line; while ((line = br.readLine()) != null) { ObjectId id = ObjectId.fromString(line.substring(0, 40)); @@ -227,7 +227,7 @@ class WriteReftable extends TextBuiltin { List<LogEntry> log = new ArrayList<>(); try (BufferedReader br = new BufferedReader( - new InputStreamReader(new FileInputStream(logPath), CHARSET))) { + new InputStreamReader(new FileInputStream(logPath), UTF_8))) { @SuppressWarnings("nls") Pattern pattern = Pattern.compile("([^,]+)" // 1: ref + ",([0-9]+(?:[.][0-9]+)?)" // 2: time diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java index 5cc98ca8ac..b97aa5b7af 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java @@ -177,7 +177,7 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser { } try { - super.parseArgument(tmp.toArray(new String[tmp.size()])); + super.parseArgument(tmp.toArray(new String[0])); } catch (Die e) { if (!seenHelp) { throw e; diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index 4b83fb0228..689db22b3a 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF @@ -3,58 +3,58 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.test Bundle-SymbolicName: org.eclipse.jgit.test -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", com.jcraft.jsch;version="[0.1.54,0.2.0)", - org.eclipse.jgit.api;version="[5.0.4,5.1.0)", - org.eclipse.jgit.api.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.attributes;version="[5.0.4,5.1.0)", - org.eclipse.jgit.awtui;version="[5.0.4,5.1.0)", - org.eclipse.jgit.blame;version="[5.0.4,5.1.0)", - org.eclipse.jgit.diff;version="[5.0.4,5.1.0)", - org.eclipse.jgit.dircache;version="[5.0.4,5.1.0)", - org.eclipse.jgit.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.events;version="[5.0.4,5.1.0)", - org.eclipse.jgit.fnmatch;version="[5.0.4,5.1.0)", - org.eclipse.jgit.gitrepo;version="[5.0.4,5.1.0)", - org.eclipse.jgit.hooks;version="[5.0.4,5.1.0)", - org.eclipse.jgit.ignore;version="[5.0.4,5.1.0)", - org.eclipse.jgit.ignore.internal;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.fsck;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.io;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.pack;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.reftable;version="[5.0.4,5.1.0)", - org.eclipse.jgit.internal.storage.reftree;version="[5.0.4,5.1.0)", - org.eclipse.jgit.junit;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lfs;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.merge;version="[5.0.4,5.1.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.notes;version="[5.0.4,5.1.0)", - org.eclipse.jgit.patch;version="[5.0.4,5.1.0)", - org.eclipse.jgit.pgm;version="[5.0.4,5.1.0)", - org.eclipse.jgit.pgm.internal;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revplot;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk.filter;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.file;version="[5.0.4,5.1.0)", - org.eclipse.jgit.storage.pack;version="[5.0.4,5.1.0)", - org.eclipse.jgit.submodule;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.http;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport.resolver;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.treewalk.filter;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util.io;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util.sha1;version="[5.0.4,5.1.0)", + org.eclipse.jgit.api;version="[5.1.3,5.2.0)", + org.eclipse.jgit.api.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.attributes;version="[5.1.3,5.2.0)", + org.eclipse.jgit.awtui;version="[5.1.3,5.2.0)", + org.eclipse.jgit.blame;version="[5.1.3,5.2.0)", + org.eclipse.jgit.diff;version="[5.1.3,5.2.0)", + org.eclipse.jgit.dircache;version="[5.1.3,5.2.0)", + org.eclipse.jgit.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.events;version="[5.1.3,5.2.0)", + org.eclipse.jgit.fnmatch;version="[5.1.3,5.2.0)", + org.eclipse.jgit.gitrepo;version="[5.1.3,5.2.0)", + org.eclipse.jgit.hooks;version="[5.1.3,5.2.0)", + org.eclipse.jgit.ignore;version="[5.1.3,5.2.0)", + org.eclipse.jgit.ignore.internal;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.fsck;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.io;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.pack;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.reftable;version="[5.1.3,5.2.0)", + org.eclipse.jgit.internal.storage.reftree;version="[5.1.3,5.2.0)", + org.eclipse.jgit.junit;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lfs;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.merge;version="[5.1.3,5.2.0)", + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.notes;version="[5.1.3,5.2.0)", + org.eclipse.jgit.patch;version="[5.1.3,5.2.0)", + org.eclipse.jgit.pgm;version="[5.1.3,5.2.0)", + org.eclipse.jgit.pgm.internal;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revplot;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk.filter;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.file;version="[5.1.3,5.2.0)", + org.eclipse.jgit.storage.pack;version="[5.1.3,5.2.0)", + org.eclipse.jgit.submodule;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.http;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport.resolver;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.treewalk.filter;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util.io;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util.sha1;version="[5.1.3,5.2.0)", org.junit;version="[4.12,5.0.0)", org.junit.experimental.theories;version="[4.12,5.0.0)", org.junit.rules;version="[4.12,5.0.0)", diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/ignore/CGitVsJGitRandomIgnorePatternTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/ignore/CGitVsJGitRandomIgnorePatternTest.java index 4d9e864227..438d2d625b 100644 --- a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/ignore/CGitVsJGitRandomIgnorePatternTest.java +++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/ignore/CGitVsJGitRandomIgnorePatternTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.ignore; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.BufferedReader; import java.io.File; @@ -158,7 +158,7 @@ public class CGitVsJGitRandomIgnorePatternTest { this.gitDir = gitDir; this.pattern = pattern; Files.write(FileUtils.toPath(new File(gitDir, ".gitignore")), - (pattern + "\n").getBytes(CHARSET), StandardOpenOption.CREATE, + (pattern + "\n").getBytes(UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE); } @@ -188,7 +188,7 @@ public class CGitVsJGitRandomIgnorePatternTest { Process proc = Runtime.getRuntime().exec(command, new String[0], gitDir); try (OutputStream out = proc.getOutputStream()) { - out.write((path + "\n").getBytes(CHARSET)); + out.write((path + "\n").getBytes(UTF_8)); out.flush(); } return proc; diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java index 79d8d0e10b..f597f2fe3c 100644 --- a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java +++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.patch; import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -56,7 +57,6 @@ import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.HashSet; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.util.MutableInteger; import org.eclipse.jgit.util.RawParseUtils; import org.eclipse.jgit.util.TemporaryBuffer; @@ -176,7 +176,7 @@ public class EGitPatchHistoryTest { i.added = RawParseUtils.parseBase10(buf, ptr.value, ptr); i.deleted = RawParseUtils.parseBase10(buf, ptr.value + 1, ptr); final int eol = RawParseUtils.nextLF(buf, ptr.value); - final String name = RawParseUtils.decode(Constants.CHARSET, + final String name = RawParseUtils.decode(UTF_8, buf, ptr.value + 1, eol - 1); files.put(name, i); ptr.value = eol; diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index e6c7128f19..b51cebce7a 100644 --- a/org.eclipse.jgit.test/pom.xml +++ b/org.eclipse.jgit.test/pom.xml @@ -52,7 +52,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.test</artifactId> @@ -157,7 +157,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <argLine>-Xmx256m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine> + <argLine>-Xmx1024m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine> <includes> <include>**/*Test.java</include> <include>**/*Tests.java</include> diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java index c5582a8601..228df35c76 100644 --- a/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java @@ -74,11 +74,11 @@ public class ChangeRecorder implements WorkingTreeModifiedListener { } private String[] getModified() { - return modified.toArray(new String[modified.size()]); + return modified.toArray(new String[0]); } private String[] getDeleted() { - return deleted.toArray(new String[deleted.size()]); + return deleted.toArray(new String[0]); } private void reset() { diff --git a/org.eclipse.jgit.test/tests.bzl b/org.eclipse.jgit.test/tests.bzl index f368000b21..bc06e3ef40 100644 --- a/org.eclipse.jgit.test/tests.bzl +++ b/org.eclipse.jgit.test/tests.bzl @@ -42,6 +42,10 @@ def tests(tests): "//lib:jsch", ] + heap_size = "-Xmx256m" + if src.endswith("HugeCommitMessageTest.java"): + heap_size = "-Xmx512m" + junit_tests( name = name, tags = labels, @@ -57,5 +61,5 @@ def tests(tests): "//org.eclipse.jgit.lfs:jgit-lfs", ], flaky = flaky, - jvm_flags = ["-Xmx256m", "-Dfile.encoding=UTF-8"], + jvm_flags = [heap_size, "-Dfile.encoding=UTF-8"], ) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java index bb303cc411..1e3a39aad8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java @@ -42,7 +42,7 @@ package org.eclipse.jgit.api; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.AUTO_CRLF; import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.AUTO_LF; import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.DIRECT; @@ -150,8 +150,8 @@ public class EolStreamTypeUtilTest { EolStreamType streamTypeWithBinaryCheck, String output, String expectedConversion) throws Exception { ByteArrayOutputStream b; - byte[] outputBytes = output.getBytes(CHARSET); - byte[] expectedConversionBytes = expectedConversion.getBytes(CHARSET); + byte[] outputBytes = output.getBytes(UTF_8); + byte[] expectedConversionBytes = expectedConversion.getBytes(UTF_8); // test using output text and assuming it was declared TEXT b = new ByteArrayOutputStream(); @@ -277,8 +277,8 @@ public class EolStreamTypeUtilTest { private void testCheckin(EolStreamType streamTypeText, EolStreamType streamTypeWithBinaryCheck, String input, String expectedConversion) throws Exception { - byte[] inputBytes = input.getBytes(CHARSET); - byte[] expectedConversionBytes = expectedConversion.getBytes(CHARSET); + byte[] inputBytes = input.getBytes(UTF_8); + byte[] expectedConversionBytes = expectedConversion.getBytes(UTF_8); // test using input text and assuming it was declared TEXT try (InputStream in = EolStreamTypeUtil.wrapInputStream( diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NotesCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NotesCommandTest.java index e234aa339c..6e06e9545a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NotesCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NotesCommandTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.api; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import java.util.List; @@ -88,7 +88,7 @@ public class NotesCommandTest extends RepositoryTestCase { git.notesAdd().setObjectId(commit2).setMessage("data").call(); Note note = git.notesShow().setObjectId(commit2).call(); String content = new String(db.open(note.getData()).getCachedBytes(), - CHARSET); + UTF_8); assertEquals(content, "data"); git.notesRemove().setObjectId(commit2).call(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java index 0b0e3bf3ea..9461c42500 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.api; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -592,7 +592,7 @@ public class PullCommandTest extends RepositoryTestCase { private static void writeToFile(File actFile, String string) throws IOException { try (FileOutputStream fos = new FileOutputStream(actFile)) { - fos.write(string.getBytes(CHARSET)); + fos.write(string.getBytes(UTF_8)); } } @@ -606,7 +606,7 @@ public class PullCommandTest extends RepositoryTestCase { bos.write(buffer, 0, read); read = fis.read(buffer); } - String content = new String(bos.toByteArray(), CHARSET); + String content = new String(bos.toByteArray(), UTF_8); assertEquals(string, content); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java index b349c66cab..913b4ac434 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandWithRebaseTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.api; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -396,7 +396,7 @@ public class PullCommandWithRebaseTest extends RepositoryTestCase { private static void writeToFile(File actFile, String string) throws IOException { try (FileOutputStream fos = new FileOutputStream(actFile)) { - fos.write(string.getBytes(CHARSET)); + fos.write(string.getBytes(UTF_8)); } } @@ -410,7 +410,7 @@ public class PullCommandWithRebaseTest extends RepositoryTestCase { bos.write(buffer, 0, read); read = fis.read(buffer); } - String content = new String(bos.toByteArray(), CHARSET); + String content = new String(bos.toByteArray(), UTF_8); assertEquals(string, content); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java index 1af37e25f5..ca86d81301 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java @@ -245,7 +245,7 @@ public class PushCommandTest extends RepositoryTestCase { git.add().addFilepattern("f" + i).call(); commit = git.commit().setMessage("adding f" + i).call(); git.push().setRemote("test").call(); - git2.getRepository().getAllRefs(); + git2.getRepository().getRefDatabase().getRefs(); assertEquals("failed to update on attempt " + i, commit.getId(), git2.getRepository().resolve("refs/heads/test")); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java index 96e7091ae1..4401bcedb3 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.api; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; @@ -57,9 +57,12 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.eclipse.jgit.api.MergeResult.MergeStatus; import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler; @@ -75,6 +78,7 @@ import org.eclipse.jgit.errors.AmbiguousObjectException; import org.eclipse.jgit.errors.IllegalTodoFileModification; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.events.ListenerHandle; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.jgit.lib.ConfigConstants; @@ -1464,7 +1468,7 @@ public class RebaseCommandTest extends RepositoryTestCase { assertEquals("GIT_AUTHOR_DATE='@123456789 -0100'", lines[2]); PersonIdent parsedIdent = git.rebase().parseAuthor( - convertedAuthor.getBytes(CHARSET)); + convertedAuthor.getBytes(UTF_8)); assertEquals(ident.getName(), parsedIdent.getName()); assertEquals(ident.getEmailAddress(), parsedIdent.getEmailAddress()); // this is rounded to the last second @@ -1481,7 +1485,7 @@ public class RebaseCommandTest extends RepositoryTestCase { assertEquals("GIT_AUTHOR_DATE='@123456789 +0930'", lines[2]); parsedIdent = git.rebase().parseAuthor( - convertedAuthor.getBytes(CHARSET)); + convertedAuthor.getBytes(UTF_8)); assertEquals(ident.getName(), parsedIdent.getName()); assertEquals(ident.getEmailAddress(), parsedIdent.getEmailAddress()); assertEquals(123456789000L, parsedIdent.getWhen().getTime()); @@ -1981,6 +1985,62 @@ public class RebaseCommandTest extends RepositoryTestCase { } @Test + public void testRebaseWithAutoStashAndSubdirs() throws Exception { + // create file0, add and commit + db.getConfig().setBoolean(ConfigConstants.CONFIG_REBASE_SECTION, null, + ConfigConstants.CONFIG_KEY_AUTOSTASH, true); + writeTrashFile("sub/file0", "file0"); + git.add().addFilepattern("sub/file0").call(); + git.commit().setMessage("commit0").call(); + // create file1, add and commit + writeTrashFile(FILE1, "file1"); + git.add().addFilepattern(FILE1).call(); + RevCommit commit = git.commit().setMessage("commit1").call(); + + // create topic branch and checkout / create file2, add and commit + createBranch(commit, "refs/heads/topic"); + checkoutBranch("refs/heads/topic"); + writeTrashFile("file2", "file2"); + git.add().addFilepattern("file2").call(); + git.commit().setMessage("commit2").call(); + + // checkout master branch / modify file1, add and commit + checkoutBranch("refs/heads/master"); + writeTrashFile(FILE1, "modified file1"); + git.add().addFilepattern(FILE1).call(); + git.commit().setMessage("commit3").call(); + + // checkout topic branch / modify file0 + checkoutBranch("refs/heads/topic"); + writeTrashFile("sub/file0", "unstaged modified file0"); + + Set<String> modifiedFiles = new HashSet<>(); + ListenerHandle handle = db.getListenerList() + .addWorkingTreeModifiedListener( + event -> modifiedFiles.addAll(event.getModified())); + try { + // rebase + assertEquals(Status.OK, git.rebase() + .setUpstream("refs/heads/master").call().getStatus()); + } finally { + handle.remove(); + } + checkFile(new File(new File(db.getWorkTree(), "sub"), "file0"), + "unstaged modified file0"); + checkFile(new File(db.getWorkTree(), FILE1), "modified file1"); + checkFile(new File(db.getWorkTree(), "file2"), "file2"); + assertEquals( + "[file1, mode:100644, content:modified file1]" + + "[file2, mode:100644, content:file2]" + + "[sub/file0, mode:100644, content:file0]", + indexState(CONTENT)); + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + List<String> modified = new ArrayList<>(modifiedFiles); + Collections.sort(modified); + assertEquals("[file1, sub/file0]", modified.toString()); + } + + @Test public void testRebaseWithAutoStashConflictOnApply() throws Exception { // create file0, add and commit db.getConfig().setBoolean(ConfigConstants.CONFIG_REBASE_SECTION, null, @@ -2104,7 +2164,7 @@ public class RebaseCommandTest extends RepositoryTestCase { int count = 0; File todoFile = getTodoFile(); try (BufferedReader br = new BufferedReader(new InputStreamReader( - new FileInputStream(todoFile), CHARSET))) { + new FileInputStream(todoFile), UTF_8))) { String line = br.readLine(); while (line != null) { int firstBlank = line.indexOf(' '); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ReflogCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ReflogCommandTest.java index b07c7033f5..8922837139 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ReflogCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ReflogCommandTest.java @@ -89,7 +89,7 @@ public class ReflogCommandTest extends RepositoryTestCase { Collection<ReflogEntry> reflog = git.reflog().call(); assertNotNull(reflog); assertEquals(3, reflog.size()); - ReflogEntry[] reflogs = reflog.toArray(new ReflogEntry[reflog.size()]); + ReflogEntry[] reflogs = reflog.toArray(new ReflogEntry[0]); assertEquals(reflogs[2].getComment(), "commit (initial): Initial commit"); assertEquals(reflogs[2].getNewId(), commit1.getId()); @@ -114,7 +114,7 @@ public class ReflogCommandTest extends RepositoryTestCase { .setRef(Constants.R_HEADS + "b1").call(); assertNotNull(reflog); assertEquals(2, reflog.size()); - ReflogEntry[] reflogs = reflog.toArray(new ReflogEntry[reflog.size()]); + ReflogEntry[] reflogs = reflog.toArray(new ReflogEntry[0]); assertEquals(reflogs[0].getComment(), "commit: Removed file"); assertEquals(reflogs[0].getNewId(), commit2.getId()); assertEquals(reflogs[0].getOldId(), commit1.getId()); @@ -136,7 +136,7 @@ public class ReflogCommandTest extends RepositoryTestCase { Collection<ReflogEntry> reflog = git.reflog().call(); assertNotNull(reflog); assertEquals(4, reflog.size()); - ReflogEntry[] reflogs = reflog.toArray(new ReflogEntry[reflog.size()]); + ReflogEntry[] reflogs = reflog.toArray(new ReflogEntry[0]); assertEquals(reflogs[3].getComment(), "commit (initial): Initial commit"); assertEquals(reflogs[3].getNewId(), commit1.getId()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java index 8f56a9270e..2b97b307bf 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2013, Chris Aniszczyk <caniszczyk@gmail.com> + * Copyright (C) 2011-2018, Chris Aniszczyk <caniszczyk@gmail.com> * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -52,7 +52,6 @@ import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; -import java.io.PrintWriter; import org.eclipse.jgit.api.ResetCommand.ResetType; import org.eclipse.jgit.api.errors.GitAPIException; @@ -94,45 +93,25 @@ public class ResetCommandTest extends RepositoryTestCase { git = new Git(db); initialCommit = git.commit().setMessage("initial commit").call(); + // create file + indexFile = writeTrashFile("a.txt", "content"); + // create nested file - File dir = new File(db.getWorkTree(), "dir"); - FileUtils.mkdir(dir); - File nestedFile = new File(dir, "b.txt"); - FileUtils.createNewFile(nestedFile); - - try (PrintWriter nestedFileWriter = new PrintWriter(nestedFile)) { - nestedFileWriter.print("content"); - nestedFileWriter.flush(); - - // create file - indexFile = new File(db.getWorkTree(), "a.txt"); - FileUtils.createNewFile(indexFile); - try (PrintWriter writer = new PrintWriter(indexFile)) { - writer.print("content"); - writer.flush(); - - // add file and commit it - git.add().addFilepattern("dir").addFilepattern("a.txt").call(); - secondCommit = git.commit() - .setMessage("adding a.txt and dir/b.txt").call(); - - prestage = DirCache.read(db.getIndexFile(), db.getFS()) - .getEntry(indexFile.getName()); - - // modify file and add to index - writer.print("new content"); - } - nestedFileWriter.print("new content"); - } - git.add().addFilepattern("a.txt").addFilepattern("dir").call(); + writeTrashFile("dir/b.txt", "content"); + + // add files and commit them + git.add().addFilepattern("a.txt").addFilepattern("dir/b.txt").call(); + secondCommit = git.commit().setMessage("adding a.txt and dir/b.txt").call(); + + prestage = DirCache.read(db.getIndexFile(), db.getFS()).getEntry(indexFile.getName()); + + // modify files and add to index + writeTrashFile("a.txt", "new content"); + writeTrashFile("dir/b.txt", "new content"); + git.add().addFilepattern("a.txt").addFilepattern("dir/b.txt").call(); // create a file not added to the index - untrackedFile = new File(db.getWorkTree(), - "notAddedToIndex.txt"); - FileUtils.createNewFile(untrackedFile); - try (PrintWriter writer2 = new PrintWriter(untrackedFile)) { - writer2.print("content"); - } + untrackedFile = writeTrashFile("notAddedToIndex.txt", "content"); } @Test @@ -179,31 +158,29 @@ public class ResetCommandTest extends RepositoryTestCase { } @Test - public void testHardResetWithConflicts_DoOverWriteUntrackedFile() - throws JGitInternalException, - AmbiguousObjectException, IOException, GitAPIException { + public void testHardResetWithConflicts_OverwriteUntrackedFile() throws Exception { setupRepository(); + git.rm().setCached(true).addFilepattern("a.txt").call(); assertTrue(new File(db.getWorkTree(), "a.txt").exists()); - git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD) - .call(); + + git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD).call(); assertTrue(new File(db.getWorkTree(), "a.txt").exists()); assertEquals("content", read(new File(db.getWorkTree(), "a.txt"))); } @Test - public void testHardResetWithConflicts_DoDeleteFileFolderConflicts() - throws JGitInternalException, - AmbiguousObjectException, IOException, GitAPIException { + public void testHardResetWithConflicts_DeleteFileFolderConflict() throws Exception { setupRepository(); - writeTrashFile("d/c.txt", "x"); - git.add().addFilepattern("d/c.txt").call(); - FileUtils.delete(new File(db.getWorkTree(), "d"), FileUtils.RECURSIVE); - writeTrashFile("d", "y"); - git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD) - .call(); - assertFalse(new File(db.getWorkTree(), "d").exists()); + writeTrashFile("dir-or-file/c.txt", "content"); + git.add().addFilepattern("dir-or-file/c.txt").call(); + + FileUtils.delete(new File(db.getWorkTree(), "dir-or-file"), FileUtils.RECURSIVE); + writeTrashFile("dir-or-file", "content"); + + git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD).call(); + assertFalse(new File(db.getWorkTree(), "dir-or-file").exists()); } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java index ad3ab7fbdf..fa6c9609f5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java @@ -234,7 +234,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { ObjectId unstashed = git.stashApply().call(); assertEquals(stashed, unstashed); assertEquals("content2", read(subfolderFile)); - recorder.assertEvent(new String[] { "d1/d2/f.txt", "d1/d2", "d1" }, + recorder.assertEvent(new String[] { "d1/d2/f.txt" }, ChangeRecorder.EMPTY); Status status = git.status().call(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/CGitAttributesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/CGitAttributesTest.java index 344d1af6a0..b6615075c0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/CGitAttributesTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/CGitAttributesTest.java @@ -42,6 +42,7 @@ */ package org.eclipse.jgit.attributes; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -57,7 +58,6 @@ import java.util.Map; import java.util.Set; import org.eclipse.jgit.junit.RepositoryTestCase; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk; @@ -127,14 +127,14 @@ public class CGitAttributesTest extends RepositoryTestCase { builder.directory(db.getWorkTree()); builder.environment().put("HOME", fs.userHome().getAbsolutePath()); ExecutionResult result = fs.execute(builder, new ByteArrayInputStream( - input.toString().getBytes(Constants.CHARSET))); + input.toString().getBytes(UTF_8))); String errorOut = toString(result.getStderr()); assertEquals("External git failed", "exit 0\n", "exit " + result.getRc() + '\n' + errorOut); LinkedHashMap<String, Attributes> map = new LinkedHashMap<>(); try (BufferedReader r = new BufferedReader(new InputStreamReader( new BufferedInputStream(result.getStdout().openInputStream()), - Constants.CHARSET))) { + UTF_8))) { r.lines().forEach(line -> { // Parse the line and add to result map int start = 0; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/AbstractDiffTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/AbstractDiffTestCase.java index 32f34213ec..0f13a68b25 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/AbstractDiffTestCase.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/AbstractDiffTestCase.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.diff; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -240,6 +240,6 @@ public abstract class AbstractDiffTestCase { r.append(text.charAt(i)); r.append('\n'); } - return new RawText(r.toString().getBytes(CHARSET)); + return new RawText(r.toString().getBytes(UTF_8)); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RawTextTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RawTextTest.java index 58a8b2d468..5885d9b7e6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RawTextTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RawTextTest.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.diff; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -147,8 +147,8 @@ public class RawTextTest { e = c.reduceCommonStartEnd(t("abQxy"), t("abRxy"), e); assertEquals(new Edit(2, 3, 2, 3), e); - RawText a = new RawText("p\na b\nQ\nc d\n".getBytes(CHARSET)); - RawText b = new RawText("p\na b \nR\n c d \n".getBytes(CHARSET)); + RawText a = new RawText("p\na b\nQ\nc d\n".getBytes(UTF_8)); + RawText b = new RawText("p\na b \nR\n c d \n".getBytes(UTF_8)); e = new Edit(0, 4, 0, 4); e = RawTextComparator.WS_IGNORE_ALL.reduceCommonStartEnd(a, b, e); assertEquals(new Edit(2, 3, 2, 3), e); @@ -160,14 +160,14 @@ public class RawTextTest { RawText b; Edit e; - a = new RawText("R\n y\n".getBytes(CHARSET)); - b = new RawText("S\n\n y\n".getBytes(CHARSET)); + a = new RawText("R\n y\n".getBytes(UTF_8)); + b = new RawText("S\n\n y\n".getBytes(UTF_8)); e = new Edit(0, 2, 0, 3); e = RawTextComparator.DEFAULT.reduceCommonStartEnd(a, b, e); assertEquals(new Edit(0, 1, 0, 2), e); - a = new RawText("S\n\n y\n".getBytes(CHARSET)); - b = new RawText("R\n y\n".getBytes(CHARSET)); + a = new RawText("S\n\n y\n".getBytes(UTF_8)); + b = new RawText("R\n y\n".getBytes(UTF_8)); e = new Edit(0, 3, 0, 2); e = RawTextComparator.DEFAULT.reduceCommonStartEnd(a, b, e); assertEquals(new Edit(0, 2, 0, 1), e); @@ -178,8 +178,8 @@ public class RawTextTest { RawText a; RawText b; Edit e; - a = new RawText("start".getBytes(CHARSET)); - b = new RawText("start of line".getBytes(CHARSET)); + a = new RawText("start".getBytes(UTF_8)); + b = new RawText("start of line".getBytes(UTF_8)); e = new Edit(0, 1, 0, 1); e = RawTextComparator.DEFAULT.reduceCommonStartEnd(a, b, e); assertEquals(new Edit(0, 1, 0, 1), e); @@ -190,8 +190,8 @@ public class RawTextTest { RawText a; RawText b; Edit e; - a = new RawText("start".getBytes(CHARSET)); - b = new RawText("start of\nlastline".getBytes(CHARSET)); + a = new RawText("start".getBytes(UTF_8)); + b = new RawText("start of\nlastline".getBytes(UTF_8)); e = new Edit(0, 1, 0, 2); e = RawTextComparator.DEFAULT.reduceCommonStartEnd(a, b, e); assertEquals(new Edit(0, 1, 0, 2), e); @@ -250,6 +250,6 @@ public class RawTextTest { r.append(text.charAt(i)); r.append('\n'); } - return new RawText(r.toString().getBytes(CHARSET)); + return new RawText(r.toString().getBytes(UTF_8)); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/SimilarityIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/SimilarityIndexTest.java index 51a6f8121c..f168e83284 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/SimilarityIndexTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/SimilarityIndexTest.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.diff; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -82,7 +82,7 @@ public class SimilarityIndexTest { + "A\n" // + "B\n" // + "B\n" // - + "B\n").getBytes(CHARSET); + + "B\n").getBytes(UTF_8); SimilarityIndex si = new SimilarityIndex(); si.hash(new ByteArrayInputStream(in), in.length, false); assertEquals(2, si.size()); @@ -130,12 +130,12 @@ public class SimilarityIndexTest { + "D\r\n" // + "B\r\n"; SimilarityIndex src = new SimilarityIndex(); - byte[] bytes1 = text.getBytes(CHARSET); + byte[] bytes1 = text.getBytes(UTF_8); src.hash(new ByteArrayInputStream(bytes1), bytes1.length, true); src.sort(); SimilarityIndex dst = new SimilarityIndex(); - byte[] bytes2 = text.replace("\r", "").getBytes(CHARSET); + byte[] bytes2 = text.replace("\r", "").getBytes(UTF_8); dst.hash(new ByteArrayInputStream(bytes2), bytes2.length, true); dst.sort(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java index c362e7497c..847d0abad4 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.dircache; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.junit.Assert.assertEquals; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -236,7 +236,7 @@ public class DirCacheCGitCompatabilityTest extends LocalDiskRepositoryTestCase { private static Map<String, CGitIndexRecord> readLsFiles() throws Exception { final LinkedHashMap<String, CGitIndexRecord> r = new LinkedHashMap<>(); try (BufferedReader br = new BufferedReader(new InputStreamReader( - new FileInputStream(pathOf("gitgit.lsfiles")), CHARSET))) { + new FileInputStream(pathOf("gitgit.lsfiles")), UTF_8))) { String line; while ((line = br.readLine()) != null) { final CGitIndexRecord cr = new CGitIndexRecord(line); @@ -249,7 +249,7 @@ public class DirCacheCGitCompatabilityTest extends LocalDiskRepositoryTestCase { private static Map<String, CGitLsTreeRecord> readLsTree() throws Exception { final LinkedHashMap<String, CGitLsTreeRecord> r = new LinkedHashMap<>(); try (BufferedReader br = new BufferedReader(new InputStreamReader( - new FileInputStream(pathOf("gitgit.lstree")), CHARSET))) { + new FileInputStream(pathOf("gitgit.lstree")), UTF_8))) { String line; while ((line = br.readLine()) != null) { final CGitLsTreeRecord cr = new CGitLsTreeRecord(line); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java index 69a48cc4b5..88a077630e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java @@ -42,7 +42,8 @@ */ package org.eclipse.jgit.gitrepo; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -51,6 +52,8 @@ import java.io.IOException; import java.net.URI; import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.junit.Test; import org.xml.sax.SAXException; @@ -82,7 +85,7 @@ public class ManifestParserTest { ManifestParser parser = new ManifestParser( null, null, "master", baseUrl, null, null); - parser.read(new ByteArrayInputStream(xmlContent.toString().getBytes(CHARSET))); + parser.read(new ByteArrayInputStream(xmlContent.toString().getBytes(UTF_8))); // Unfiltered projects should have them all. results.clear(); results.add("foo"); @@ -136,7 +139,7 @@ public class ManifestParserTest { baseUrl, null, null); try { parser.read(new ByteArrayInputStream( - xmlContent.toString().getBytes(CHARSET))); + xmlContent.toString().getBytes(UTF_8))); fail("ManifestParser did not throw exception for missing fetch"); } catch (IOException e) { assertTrue(e.getCause() instanceof SAXException); @@ -145,6 +148,29 @@ public class ManifestParserTest { } } + @Test + public void testRemoveProject() throws Exception { + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"foo\" name=\"foo\" />") + .append("<project path=\"bar\" name=\"bar\" />") + .append("<remove-project name=\"foo\" />") + .append("<project path=\"foo\" name=\"baz\" />") + .append("</manifest>"); + + ManifestParser parser = new ManifestParser(null, null, "master", + "https://git.google.com/", null, null); + parser.read(new ByteArrayInputStream( + xmlContent.toString().getBytes(UTF_8))); + + assertEquals(Stream.of("bar", "baz").collect(Collectors.toSet()), + parser.getProjects().stream().map(RepoProject::getName) + .collect(Collectors.toSet())); + } + void testNormalize(String in, String want) { URI got = ManifestParser.normalizeEmptyPath(URI.create(in)); if (!got.toString().equals(want)) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java index df31ab0869..92f0cf6196 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.gitrepo; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -217,7 +217,7 @@ public class RepoCommandTest extends RepositoryTestCase { RevCommit commit = cmd .setInputStream(new ByteArrayInputStream( - xmlContent.toString().getBytes(CHARSET))) + xmlContent.toString().getBytes(UTF_8))) .setRemoteReader(repos).setURI("platform/") .setTargetURI("platform/superproject") .setRecordRemoteBranch(true).setRecordSubmoduleLabels(true) @@ -226,7 +226,7 @@ public class RepoCommandTest extends RepositoryTestCase { String firstIdStr = commit.getId().name() + ":" + ".gitmodules"; commit = new RepoCommand(dest) .setInputStream(new ByteArrayInputStream( - xmlContent.toString().getBytes(CHARSET))) + xmlContent.toString().getBytes(UTF_8))) .setRemoteReader(repos).setURI("platform/") .setTargetURI("platform/superproject") .setRecordRemoteBranch(true).setRecordSubmoduleLabels(true) @@ -254,7 +254,7 @@ public class RepoCommandTest extends RepositoryTestCase { RevCommit commit = cmd .setInputStream(new ByteArrayInputStream( - xmlContent.toString().getBytes(CHARSET))) + xmlContent.toString().getBytes(UTF_8))) .setRemoteReader(repos).setURI("platform/") .setTargetURI("platform/superproject") .setRecordRemoteBranch(true).setRecordSubmoduleLabels(true) @@ -268,7 +268,8 @@ public class RepoCommandTest extends RepositoryTestCase { .getCachedBytes(Integer.MAX_VALUE); Config base = new Config(); BlobBasedConfig cfg = new BlobBasedConfig(base, bytes); - String subUrl = cfg.getString("submodule", "base", "url"); + String subUrl = cfg.getString("submodule", "platform/base", + "url"); assertEquals(subUrl, "../base"); } } @@ -287,7 +288,7 @@ public class RepoCommandTest extends RepositoryTestCase { try (Repository dest = cloneRepository(db, true)) { RevCommit commit = new RepoCommand(dest) .setInputStream(new ByteArrayInputStream( - xmlContent.toString().getBytes(CHARSET))) + xmlContent.toString().getBytes(UTF_8))) .setRemoteReader(new IndexedRepos()).setURI("platform/") .setTargetURI("platform/superproject") .setRecordRemoteBranch(true).setIgnoreRemoteFailures(true) @@ -301,7 +302,8 @@ public class RepoCommandTest extends RepositoryTestCase { .getCachedBytes(Integer.MAX_VALUE); Config base = new Config(); BlobBasedConfig cfg = new BlobBasedConfig(base, bytes); - String subUrl = cfg.getString("submodule", "base", "url"); + String subUrl = cfg.getString("submodule", "platform/base", + "url"); assertEquals(subUrl, "https://host.com/platform/base"); } } @@ -325,7 +327,7 @@ public class RepoCommandTest extends RepositoryTestCase { RevCommit commit = cmd .setInputStream(new ByteArrayInputStream( - xmlContent.toString().getBytes(CHARSET))) + xmlContent.toString().getBytes(UTF_8))) .setRemoteReader(repos).setURI("").setTargetURI("gerrit") .setRecordRemoteBranch(true).setRecordSubmoduleLabels(true) .call(); @@ -374,7 +376,7 @@ public class RepoCommandTest extends RepositoryTestCase { RevCommit commit = cmd .setInputStream(new ByteArrayInputStream( - xmlContent.toString().getBytes(CHARSET))) + xmlContent.toString().getBytes(UTF_8))) .setRemoteReader(repos).setURI(baseUrl) .setTargetURI("gerrit").setRecordRemoteBranch(true) .setRecordSubmoduleLabels(true).call(); @@ -387,8 +389,8 @@ public class RepoCommandTest extends RepositoryTestCase { .getCachedBytes(Integer.MAX_VALUE); Config base = new Config(); BlobBasedConfig cfg = new BlobBasedConfig(base, bytes); - String subUrl = cfg.getString("submodule", "src", - "url"); + String subUrl = cfg.getString("submodule", + "chromium/src", "url"); assertEquals( "https://chromium.googlesource.com/chromium/src", subUrl); @@ -429,7 +431,7 @@ public class RepoCommandTest extends RepositoryTestCase { RevCommit commit = cmd .setInputStream(new ByteArrayInputStream( - xmlContent.toString().getBytes(CHARSET))) + xmlContent.toString().getBytes(UTF_8))) .setRemoteReader(repos).setURI(baseUrl) .setTargetURI(abs + "/superproject") .setRecordRemoteBranch(true) @@ -443,8 +445,8 @@ public class RepoCommandTest extends RepositoryTestCase { .getCachedBytes(Integer.MAX_VALUE); Config base = new Config(); BlobBasedConfig cfg = new BlobBasedConfig(base, bytes); - String subUrl = cfg.getString("submodule", "src", - "url"); + String subUrl = cfg.getString("submodule", + "chromium/src", "url"); assertEquals("../chromium/src", subUrl); } fetchSlash = !fetchSlash; @@ -613,7 +615,7 @@ public class RepoCommandTest extends RepositoryTestCase { String content = reader.readLine(); assertEquals( "The first line of .gitmodules file should be as expected", - "[submodule \"foo\"]", content); + "[submodule \"" + defaultUri + "\"]", content); } // The gitlink should be the same as remote head sha1 String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); @@ -801,9 +803,9 @@ public class RepoCommandTest extends RepositoryTestCase { .append("<manifest>") .append("<remote name=\"remote1\" fetch=\".\" />") .append("<default revision=\"master\" remote=\"remote1\" />") - .append("<project path=\"bar\" name=\"").append(defaultUri) - .append("\" revision=\"").append(BRANCH).append("\" >") - .append("<copyfile src=\"hello.txt\" dest=\"Hello.txt\" />") + .append("<project path=\"bar\" name=\"").append(notDefaultUri) + .append("\" >") + .append("<copyfile src=\"world.txt\" dest=\"World.txt\" />") .append("</project>").append("</manifest>"); JGitTestUtil.writeTrashFile(tempDb, "new.xml", xmlContent.toString()); command = new RepoCommand(remoteDb); @@ -819,8 +821,8 @@ public class RepoCommandTest extends RepositoryTestCase { File hello = new File(localDb.getWorkTree(), "Hello"); assertFalse("The Hello file shouldn't exist", hello.exists()); // The Hello.txt file should exist - File hellotxt = new File(localDb.getWorkTree(), "Hello.txt"); - assertTrue("The Hello.txt file should exist", hellotxt.exists()); + File hellotxt = new File(localDb.getWorkTree(), "World.txt"); + assertTrue("The World.txt file should exist", hellotxt.exists()); dotmodules = new File(localDb.getWorkTree(), Constants.DOT_GIT_MODULES); } @@ -835,9 +837,9 @@ public class RepoCommandTest extends RepositoryTestCase { String line = reader.readLine(); if (line == null) break; - if (line.contains("submodule \"foo\"")) + if (line.contains("submodule \"" + defaultUri + "\"")) foo = true; - if (line.contains("submodule \"bar\"")) + if (line.contains("submodule \"" + notDefaultUri + "\"")) bar = true; } assertTrue("The bar submodule should exist", bar); @@ -876,9 +878,7 @@ public class RepoCommandTest extends RepositoryTestCase { Constants.DOT_GIT_MODULES); } - // The .gitmodules file should have 'submodule "foo"' and shouldn't - // have - // 'submodule "foo/bar"' lines. + // Check .gitmodules file try (BufferedReader reader = new BufferedReader( new FileReader(dotmodules))) { boolean foo = false; @@ -888,16 +888,17 @@ public class RepoCommandTest extends RepositoryTestCase { String line = reader.readLine(); if (line == null) break; - if (line.contains("submodule \"foo\"")) + if (line.contains("submodule \"" + defaultUri + "\"")) foo = true; - if (line.contains("submodule \"foo/bar\"")) + if (line.contains("submodule \"" + groupBUri + "\"")) foobar = true; - if (line.contains("submodule \"a\"")) + if (line.contains("submodule \"" + groupAUri + "\"")) a = true; } - assertTrue("The foo submodule should exist", foo); - assertFalse("The foo/bar submodule shouldn't exist", foobar); - assertTrue("The a submodule should exist", a); + assertTrue("The " + defaultUri + " submodule should exist", foo); + assertFalse("The " + groupBUri + " submodule shouldn't exist", + foobar); + assertTrue("The " + groupAUri + " submodule should exist", a); } } @@ -1033,11 +1034,11 @@ public class RepoCommandTest extends RepositoryTestCase { assertEquals( "Recording remote branches should work for short branch descriptions", "master", - c.getString("submodule", "with-branch", "branch")); + c.getString("submodule", notDefaultUri, "branch")); assertEquals( "Recording remote branches should work for full ref specs", "refs/heads/master", - c.getString("submodule", "with-long-branch", "branch")); + c.getString("submodule", defaultUri, "branch")); } } @@ -1095,7 +1096,7 @@ public class RepoCommandTest extends RepositoryTestCase { .append("<project path=\"shallow-please\" ").append("name=\"") .append(defaultUri).append("\" ").append("clone-depth=\"1\" />") .append("<project path=\"non-shallow\" ").append("name=\"") - .append(defaultUri).append("\" />").append("</manifest>"); + .append(notDefaultUri).append("\" />").append("</manifest>"); JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", xmlContent.toString()); @@ -1115,9 +1116,9 @@ public class RepoCommandTest extends RepositoryTestCase { FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED); c.load(); assertEquals("Recording shallow configuration should work", "true", - c.getString("submodule", "shallow-please", "shallow")); + c.getString("submodule", defaultUri, "shallow")); assertNull("Recording non shallow configuration should work", - c.getString("submodule", "non-shallow", "shallow")); + c.getString("submodule", notDefaultUri, "shallow")); } } @@ -1176,6 +1177,43 @@ public class RepoCommandTest extends RepositoryTestCase { } } + @Test + public void testTwoPathUseTheSameName() throws Exception { + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"path1\" ").append("name=\"") + .append(defaultUri).append("\" />") + .append("<project path=\"path2\" ").append("name=\"") + .append(defaultUri).append("\" />").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).setRecommendShallow(true).call(); + File directory = createTempDirectory("testBareRepo"); + try (Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository();) { + File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); + assertTrue("The .gitmodules file should exist", + gitmodules.exists()); + FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED); + c.load(); + assertEquals("A module should exist for path1", "path1", + c.getString("submodule", defaultUri + "/path1", "path")); + assertEquals("A module should exist for path2", "path2", + c.getString("submodule", defaultUri + "/path2", "path")); + } + } + private void resolveRelativeUris() { // Find the longest common prefix ends with "/" as rootUri. defaultUri = defaultDb.getDirectory().toURI().toString(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java index 0c6ed0c19e..b4c20a7e4c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java @@ -42,6 +42,7 @@ */ package org.eclipse.jgit.ignore; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -56,7 +57,6 @@ import java.util.LinkedHashSet; import java.util.Set; import org.eclipse.jgit.junit.RepositoryTestCase; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk; @@ -113,7 +113,7 @@ public class CGitIgnoreTest extends RepositoryTestCase { "exit " + result.getRc() + '\n' + errorOut); try (BufferedReader r = new BufferedReader(new InputStreamReader( new BufferedInputStream(result.getStdout().openInputStream()), - Constants.CHARSET))) { + UTF_8))) { return r.lines().toArray(String[]::new); } } @@ -131,7 +131,7 @@ public class CGitIgnoreTest extends RepositoryTestCase { "exit " + result.getRc() + '\n' + errorOut); try (BufferedReader r = new BufferedReader(new InputStreamReader( new BufferedInputStream(result.getStdout().openInputStream()), - Constants.CHARSET))) { + UTF_8))) { return r.lines().toArray(String[]::new); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java index 78d9a82c24..cbc0761463 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.ignore; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -767,6 +767,6 @@ public class IgnoreNodeTest extends RepositoryTestCase { for (String line : rules) { data.append(line + "\n"); } - return new ByteArrayInputStream(data.toString().getBytes(CHARSET)); + return new ByteArrayInputStream(data.toString().getBytes(UTF_8)); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java index 26c11c7eb7..7e513d2c39 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java @@ -41,7 +41,7 @@ */ package org.eclipse.jgit.indexdiff; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -128,7 +128,7 @@ public class IndexDiffWithSymlinkTest extends LocalDiskRepositoryTestCase { File restoreScript = new File(testDir, name + ".sh"); try (OutputStream out = new BufferedOutputStream( new FileOutputStream(restoreScript)); - Writer writer = new OutputStreamWriter(out, CHARSET)) { + Writer writer = new OutputStreamWriter(out, UTF_8)) { writer.write("echo `which git` 1>&2\n"); writer.write("echo `git --version` 1>&2\n"); writer.write("git init " + name + " && \\\n"); @@ -170,7 +170,7 @@ public class IndexDiffWithSymlinkTest extends LocalDiskRepositoryTestCase { private String readStream(InputStream stream) throws IOException { try (BufferedReader in = new BufferedReader( - new InputStreamReader(stream))) { + new InputStreamReader(stream, UTF_8))) { StringBuilder out = new StringBuilder(); String line; while ((line = in.readLine()) != null) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java index 5b567d00f7..bfa30d5b4b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java @@ -972,7 +972,7 @@ public class DfsGarbageCollectorTest { private static boolean isReachable(Repository repo, AnyObjectId id) throws IOException { try (RevWalk rw = new RevWalk(repo)) { - for (Ref ref : repo.getAllRefs().values()) { + for (Ref ref : repo.getRefDatabase().getRefs()) { rw.markStart(rw.parseCommit(ref.getObjectId())); } for (RevCommit next; (next = rw.next()) != null;) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackDescriptionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackDescriptionTest.java new file mode 100644 index 0000000000..55e1a9c4cc --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackDescriptionTest.java @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2018, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.internal.storage.dfs; + +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_TXN; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.RECEIVE; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE; +import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; +import static org.junit.Assert.assertEquals; + +import java.util.Comparator; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; +import org.junit.Before; +import org.junit.Test; + +public final class DfsPackDescriptionTest { + private AtomicInteger counter; + + @Before + public void setUp() { + counter = new AtomicInteger(); + } + + @Test + public void objectLookupComparatorEqual() throws Exception { + DfsPackDescription a = create(RECEIVE); + a.setFileSize(PACK, 1); + a.setFileSize(INDEX, 1); + a.setLastModified(1); + a.setObjectCount(1); + a.setMaxUpdateIndex(1); + + DfsPackDescription b = create(INSERT); + b.setFileSize(PACK, 1); + b.setFileSize(INDEX, 2); + b.setLastModified(1); + b.setObjectCount(1); + b.setMaxUpdateIndex(2); + + assertComparesEqual(DfsPackDescription.objectLookupComparator(), a, b); + } + + @Test + public void objectLookupComparatorPackSource() throws Exception { + DfsPackDescription a = create(COMPACT); + a.setFileSize(PACK, 2); + a.setLastModified(1); + a.setObjectCount(2); + + DfsPackDescription b = create(GC); + b.setFileSize(PACK, 1); + b.setLastModified(2); + b.setObjectCount(1); + + assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b); + } + + @Test + public void objectLookupComparatorCustomPackSourceComparator() + throws Exception { + DfsPackDescription a = create(GC); + + DfsPackDescription b = create(COMPACT); + + assertComparesLessThan(DfsPackDescription.objectLookupComparator(), b, a); + assertComparesLessThan( + DfsPackDescription.objectLookupComparator( + new PackSource.ComparatorBuilder() + .add(GC) + .add(INSERT, RECEIVE, GC_REST, GC_TXN, UNREACHABLE_GARBAGE) + .add(COMPACT) + .build()), + a, b); + } + + @Test + public void objectLookupComparatorGcFileSize() throws Exception { + // a is older and smaller. + DfsPackDescription a = create(GC_REST); + a.setFileSize(PACK, 100); + a.setLastModified(1); + a.setObjectCount(2); + + // b is newer and larger. + DfsPackDescription b = create(GC_REST); + b.setFileSize(PACK, 200); + b.setLastModified(2); + b.setObjectCount(1); + + // Since they have the same GC type, tiebreaker is size, and a comes first. + assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b); + } + + @Test + public void objectLookupComparatorNonGcLastModified() + throws Exception { + // a is older and smaller. + DfsPackDescription a = create(INSERT); + a.setFileSize(PACK, 100); + a.setLastModified(1); + a.setObjectCount(2); + + // b is newer and larger. + DfsPackDescription b = create(INSERT); + b.setFileSize(PACK, 200); + b.setLastModified(2); + b.setObjectCount(1); + + // Since they have the same type but not GC, tiebreaker is last modified, + // and b comes first. + assertComparesLessThan(DfsPackDescription.objectLookupComparator(), b, a); + } + + @Test + public void objectLookupComparatorObjectCount() throws Exception { + DfsPackDescription a = create(INSERT); + a.setObjectCount(1); + + DfsPackDescription b = create(INSERT); + b.setObjectCount(2); + + assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b); + } + + @Test + public void reftableComparatorEqual() throws Exception { + DfsPackDescription a = create(INSERT); + a.setFileSize(PACK, 100); + a.setObjectCount(1); + + DfsPackDescription b = create(INSERT); + b.setFileSize(PACK, 200); + a.setObjectCount(2); + + assertComparesEqual(DfsPackDescription.reftableComparator(), a, b); + } + + @Test + public void reftableComparatorPackSource() throws Exception { + DfsPackDescription a = create(INSERT); + a.setMaxUpdateIndex(1); + a.setLastModified(1); + + DfsPackDescription b = create(GC); + b.setMaxUpdateIndex(2); + b.setLastModified(2); + + assertComparesLessThan(DfsPackDescription.reftableComparator(), b, a); + } + + @Test + public void reftableComparatorMaxUpdateIndex() throws Exception { + DfsPackDescription a = create(INSERT); + a.setMaxUpdateIndex(1); + a.setLastModified(2); + + DfsPackDescription b = create(INSERT); + b.setMaxUpdateIndex(2); + b.setLastModified(1); + + assertComparesLessThan(DfsPackDescription.reftableComparator(), a, b); + } + + @Test + public void reftableComparatorLastModified() throws Exception { + DfsPackDescription a = create(INSERT); + a.setLastModified(1); + + DfsPackDescription b = create(INSERT); + b.setLastModified(2); + + assertComparesLessThan(DfsPackDescription.reftableComparator(), a, b); + } + + @Test + public void reuseComparatorEqual() throws Exception { + DfsPackDescription a = create(RECEIVE); + a.setFileSize(PACK, 1); + a.setFileSize(INDEX, 1); + a.setLastModified(1); + a.setObjectCount(1); + a.setMaxUpdateIndex(1); + + DfsPackDescription b = create(INSERT); + b.setFileSize(PACK, 2); + b.setFileSize(INDEX, 2); + b.setLastModified(2); + b.setObjectCount(2); + b.setMaxUpdateIndex(2); + + assertComparesEqual(DfsPackDescription.reuseComparator(), a, b); + } + + @Test + public void reuseComparatorGcPackSize() throws Exception { + DfsPackDescription a = create(GC_REST); + a.setFileSize(PACK, 1); + a.setFileSize(INDEX, 1); + a.setLastModified(2); + a.setObjectCount(1); + a.setMaxUpdateIndex(1); + + DfsPackDescription b = create(GC_REST); + b.setFileSize(PACK, 2); + b.setFileSize(INDEX, 2); + b.setLastModified(1); + b.setObjectCount(2); + b.setMaxUpdateIndex(2); + + assertComparesLessThan(DfsPackDescription.reuseComparator(), b, a); + } + + private DfsPackDescription create(PackSource source) { + return new DfsPackDescription( + new DfsRepositoryDescription("repo"), + "pack_" + counter.incrementAndGet(), + source); + } + + private static <T> void assertComparesEqual( + Comparator<T> comparator, T o1, T o2) { + assertEquals( + "first object must compare equal to itself", + 0, comparator.compare(o1, o1)); + assertEquals( + "second object must compare equal to itself", + 0, comparator.compare(o2, o2)); + assertEquals( + "first object must compare equal to second object", + 0, comparator.compare(o1, o2)); + } + + private static <T> void assertComparesLessThan( + Comparator<T> comparator, T o1, T o2) { + assertEquals( + "first object must compare equal to itself", + 0, comparator.compare(o1, o1)); + assertEquals( + "second object must compare equal to itself", + 0, comparator.compare(o2, o2)); + assertEquals( + "first object must compare less than second object", + -1, comparator.compare(o1, o2)); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/PackSourceTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/PackSourceTest.java new file mode 100644 index 0000000000..7bf1f587f8 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/PackSourceTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.internal.storage.dfs; + +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.DEFAULT_COMPARATOR; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_TXN; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.RECEIVE; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class PackSourceTest { + @Test + public void defaultComaprator() throws Exception { + assertEquals(0, DEFAULT_COMPARATOR.compare(INSERT, INSERT)); + assertEquals(0, DEFAULT_COMPARATOR.compare(RECEIVE, RECEIVE)); + assertEquals(0, DEFAULT_COMPARATOR.compare(COMPACT, COMPACT)); + assertEquals(0, DEFAULT_COMPARATOR.compare(GC, GC)); + assertEquals(0, DEFAULT_COMPARATOR.compare(GC_REST, GC_REST)); + assertEquals(0, DEFAULT_COMPARATOR.compare(GC_TXN, GC_TXN)); + assertEquals(0, DEFAULT_COMPARATOR.compare(UNREACHABLE_GARBAGE, UNREACHABLE_GARBAGE)); + + assertEquals(0, DEFAULT_COMPARATOR.compare(INSERT, RECEIVE)); + assertEquals(0, DEFAULT_COMPARATOR.compare(RECEIVE, INSERT)); + + assertEquals(-1, DEFAULT_COMPARATOR.compare(INSERT, COMPACT)); + assertEquals(1, DEFAULT_COMPARATOR.compare(COMPACT, INSERT)); + + assertEquals(-1, DEFAULT_COMPARATOR.compare(RECEIVE, COMPACT)); + assertEquals(1, DEFAULT_COMPARATOR.compare(COMPACT, RECEIVE)); + + assertEquals(-1, DEFAULT_COMPARATOR.compare(COMPACT, GC)); + assertEquals(1, DEFAULT_COMPARATOR.compare(GC, COMPACT)); + + assertEquals(-1, DEFAULT_COMPARATOR.compare(GC, GC_REST)); + assertEquals(1, DEFAULT_COMPARATOR.compare(GC_REST, GC)); + + assertEquals(-1, DEFAULT_COMPARATOR.compare(GC_REST, GC_TXN)); + assertEquals(1, DEFAULT_COMPARATOR.compare(GC_TXN, GC_REST)); + + assertEquals(-1, DEFAULT_COMPARATOR.compare(GC_TXN, UNREACHABLE_GARBAGE)); + assertEquals(1, DEFAULT_COMPARATOR.compare(UNREACHABLE_GARBAGE, GC_TXN)); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java index e1adeedc54..3a43564180 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java @@ -46,7 +46,7 @@ package org.eclipse.jgit.internal.storage.file; import static org.eclipse.jgit.junit.Assert.assertEquals; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -263,7 +263,7 @@ public class RefUpdateTest extends SampleDataRepositoryTestCase { ObjectId blobId; try (ObjectInserter ins = bareRepo.newObjectInserter()) { - blobId = ins.insert(Constants.OBJ_BLOB, "contents".getBytes(CHARSET)); + blobId = ins.insert(Constants.OBJ_BLOB, "contents".getBytes(UTF_8)); ins.flush(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java index e113db12ac..02073226d0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java @@ -47,7 +47,7 @@ package org.eclipse.jgit.internal.storage.file; import static java.nio.charset.StandardCharsets.ISO_8859_1; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -368,7 +368,7 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { + " email = A U Thor <thor@example.com> # Just an example...\n" + " name = \"A Thor \\\\ \\\"\\t \"\n" + " defaultCheckInComment = a many line\\ncomment\\n to test\n"; - assertEquals(expectedStr, new String(IO.readFully(cfg), Constants.CHARSET)); + assertEquals(expectedStr, new String(IO.readFully(cfg), UTF_8)); } @Test @@ -517,7 +517,7 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { 4294967295000L, 60)); commit.setCommitter(new PersonIdent("Joe Hacker", "joe2@example.com", 4294967295000L, 60)); - commit.setEncoding(CHARSET); + commit.setEncoding(UTF_8); commit.setMessage("\u00dcbergeeks"); ObjectId cid = insertCommit(commit); assertEquals("4680908112778718f37e686cbebcc912730b3154", cid.name()); @@ -559,7 +559,7 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { final ObjectId treeId; try (ObjectInserter oi = db.newObjectInserter()) { final ObjectId blobId = oi.insert(Constants.OBJ_BLOB, - "and this is the data in me\n".getBytes(Constants.CHARSET + "and this is the data in me\n".getBytes(UTF_8 .name())); TreeFormatter fmt = new TreeFormatter(); fmt.append("i-am-a-file", FileMode.REGULAR_FILE, blobId); @@ -666,9 +666,9 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { ObjectId id2; try (ObjectInserter ins = db.newObjectInserter()) { id1 = ins.insert( - Constants.OBJ_BLOB, "contents1".getBytes(Constants.CHARSET)); + Constants.OBJ_BLOB, "contents1".getBytes(UTF_8)); id2 = ins.insert( - Constants.OBJ_BLOB, "contents2".getBytes(Constants.CHARSET)); + Constants.OBJ_BLOB, "contents2".getBytes(UTF_8)); ins.flush(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/WindowCacheGetTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/WindowCacheGetTest.java index 82ad28ed21..01426eeb8c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/WindowCacheGetTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/WindowCacheGetTest.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.internal.storage.file; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -77,7 +78,7 @@ public class WindowCacheGetTest extends SampleDataRepositoryTestCase { try (BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(JGitTestUtil .getTestResourceFile("all_packed_objects.txt")), - Constants.CHARSET))) { + UTF_8))) { String line; while ((line = br.readLine()) != null) { final String[] parts = line.split(" {1,}"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java index d9b58e206f..ffb6f4ee77 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java @@ -50,6 +50,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; @@ -243,7 +244,8 @@ public class GcCommitSelectionTest extends GcTestCase { List<RevCommit> commits = Arrays.asList(m0, m1, m2, b3, m4, b5, m6, b7, m8, m9); - PackWriterBitmapPreparer preparer = newPeparer(m9, commits); + PackWriterBitmapPreparer preparer = newPreparer( + Collections.singleton(m9), commits, new PackConfig()); List<BitmapCommit> selection = new ArrayList<>( preparer.selectCommits(commits.size(), PackWriter.NONE)); @@ -267,15 +269,107 @@ public class GcCommitSelectionTest extends GcTestCase { return commit.create(); } - private PackWriterBitmapPreparer newPeparer(RevCommit want, - List<RevCommit> commits) - throws IOException { + @Test + public void testDistributionOnMultipleBranches() throws Exception { + BranchBuilder[] branches = { tr.branch("refs/heads/main"), + tr.branch("refs/heads/a"), tr.branch("refs/heads/b"), + tr.branch("refs/heads/c") }; + RevCommit[] tips = new RevCommit[branches.length]; + List<RevCommit> commits = createHistory(branches, tips); + PackConfig config = new PackConfig(); + config.setBitmapContiguousCommitCount(1); + config.setBitmapRecentCommitSpan(5); + config.setBitmapDistantCommitSpan(20); + config.setBitmapRecentCommitCount(100); + Set<RevCommit> wants = new HashSet<>(Arrays.asList(tips)); + PackWriterBitmapPreparer preparer = newPreparer(wants, commits, config); + List<BitmapCommit> selection = new ArrayList<>( + preparer.selectCommits(commits.size(), PackWriter.NONE)); + Set<ObjectId> selected = new HashSet<>(); + for (BitmapCommit c : selection) { + selected.add(c.toObjectId()); + } + + // Verify that each branch has uniform bitmap selection coverage + for (RevCommit c : wants) { + assertTrue(selected.contains(c.toObjectId())); + int count = 1; + int selectedCount = 1; + RevCommit parent = c; + while (parent.getParentCount() != 0) { + parent = parent.getParent(0); + count++; + if (selected.contains(parent.toObjectId())) { + selectedCount++; + } + } + // The selection algorithm prefers merges and will look in the + // current range plus the recent commit span before selecting a + // commit. Since this history has no merges, we expect the recent + // span should have 100/10=10 and distant commit spans should have + // 100/25=4 per 100 commit range. + int expectedCount = 10 + (count - 100 - 24) / 25; + assertTrue(expectedCount <= selectedCount); + } + } + + private List<RevCommit> createHistory(BranchBuilder[] branches, + RevCommit[] tips) throws Exception { + /*- + * Create a history like this, where branches a, b and c branch off of the main branch + * at commits 100, 200 and 300, and where commit times move forward alternating between + * branches. + * + * o...o...o...o...o commits root,m0,m1,...,m399 + * \ \ \ + * \ \ o... commits branch_c,c300,c301,...,c399 + * \ \ + * \ o...o... commits branch_b,b200,b201,...,b399 + * \ + * o...o...o... commits branch_a,b100,b101,...,a399 + */ + List<RevCommit> commits = new ArrayList<>(); + String[] prefixes = { "m", "a", "b", "c" }; + int branchCount = branches.length; + tips[0] = addCommit(commits, branches[0], "root"); + int counter = 0; + + for (int b = 0; b < branchCount; b++) { + for (int i = 0; i < 100; i++, counter++) { + for (int j = 0; j <= b; j++) { + tips[j] = addCommit(commits, branches[j], + prefixes[j] + counter); + } + } + // Create a new branch from current value of the master branch + if (b < branchCount - 1) { + tips[b + 1] = addCommit(branches[b + 1], + "branch_" + prefixes[b + 1], tips[0]); + } + } + return commits; + } + + private RevCommit addCommit(List<RevCommit> commits, BranchBuilder bb, + String msg, RevCommit... parents) throws Exception { + CommitBuilder commit = bb.commit().message(msg).add(msg, msg).tick(1); + if (parents.length > 0) { + commit.noParents(); + for (RevCommit parent : parents) { + commit.parent(parent); + } + } + RevCommit c = commit.create(); + commits.add(c); + return c; + } + + private PackWriterBitmapPreparer newPreparer(Set<RevCommit> wants, + List<RevCommit> commits, PackConfig config) throws IOException { List<ObjectToPack> objects = new ArrayList<>(commits.size()); for (RevCommit commit : commits) { objects.add(new ObjectToPack(commit, Constants.OBJ_COMMIT)); } - Set<ObjectId> wants = Collections.singleton((ObjectId) want); - PackConfig config = new PackConfig(); PackBitmapIndexBuilder builder = new PackBitmapIndexBuilder(objects); return new PackWriterBitmapPreparer( tr.getRepository().newObjectReader(), builder, diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java index ec60bd9137..1d11573b99 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java @@ -80,7 +80,7 @@ public class MergedReftableTest { try (RefCursor rc = mr.seekRef(HEAD)) { assertFalse(rc.next()); } - try (RefCursor rc = mr.seekRef(R_HEADS)) { + try (RefCursor rc = mr.seekRefsWithPrefix(R_HEADS)) { assertFalse(rc.next()); } } @@ -94,7 +94,7 @@ public class MergedReftableTest { try (RefCursor rc = mr.seekRef(HEAD)) { assertFalse(rc.next()); } - try (RefCursor rc = mr.seekRef(R_HEADS)) { + try (RefCursor rc = mr.seekRefsWithPrefix(R_HEADS)) { assertFalse(rc.next()); } } @@ -108,7 +108,7 @@ public class MergedReftableTest { try (RefCursor rc = mr.seekRef(HEAD)) { assertFalse(rc.next()); } - try (RefCursor rc = mr.seekRef(R_HEADS)) { + try (RefCursor rc = mr.seekRefsWithPrefix(R_HEADS)) { assertFalse(rc.next()); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java index 3ea3061e38..0ee785c60c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java @@ -101,7 +101,7 @@ public class ReftableTest { try (RefCursor rc = t.seekRef(HEAD)) { assertFalse(rc.next()); } - try (RefCursor rc = t.seekRef(R_HEADS)) { + try (RefCursor rc = t.seekRefsWithPrefix(R_HEADS)) { assertFalse(rc.next()); } try (LogCursor rc = t.allLogs()) { @@ -317,10 +317,10 @@ public class ReftableTest { public void namespaceNotFound() throws IOException { Ref exp = ref(MASTER, 1); ReftableReader t = read(write(exp)); - try (RefCursor rc = t.seekRef("refs/changes/")) { + try (RefCursor rc = t.seekRefsWithPrefix("refs/changes/")) { assertFalse(rc.next()); } - try (RefCursor rc = t.seekRef("refs/tags/")) { + try (RefCursor rc = t.seekRefsWithPrefix("refs/tags/")) { assertFalse(rc.next()); } } @@ -332,12 +332,12 @@ public class ReftableTest { Ref v1 = tag(V1_0, 3, 4); ReftableReader t = read(write(master, next, v1)); - try (RefCursor rc = t.seekRef("refs/tags/")) { + try (RefCursor rc = t.seekRefsWithPrefix("refs/tags/")) { assertTrue(rc.next()); assertEquals(V1_0, rc.getRef().getName()); assertFalse(rc.next()); } - try (RefCursor rc = t.seekRef("refs/heads/")) { + try (RefCursor rc = t.seekRefsWithPrefix("refs/heads/")) { assertTrue(rc.next()); assertEquals(MASTER, rc.getRef().getName()); @@ -484,7 +484,7 @@ public class ReftableTest { try (RefCursor rc = t.allRefs()) { assertFalse(rc.next()); } - try (RefCursor rc = t.seekRef("refs/heads/")) { + try (RefCursor rc = t.seekRefsWithPrefix("refs/heads/")) { assertFalse(rc.next()); } try (LogCursor lc = t.allLogs()) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/junit/TestRepositoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/junit/TestRepositoryTest.java index 965899e7a0..b7027f3272 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/junit/TestRepositoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/junit/TestRepositoryTest.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.junit; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; @@ -418,6 +418,6 @@ public class TestRepositoryTest { RevObject obj = tr.get(rw.parseTree(treeish), path); assertSame(RevBlob.class, obj.getClass()); ObjectLoader loader = rw.getObjectReader().open(obj); - return new String(loader.getCachedBytes(), CHARSET); + return new String(loader.getCachedBytes(), UTF_8); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/HugeCommitMessageTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/HugeCommitMessageTest.java new file mode 100644 index 0000000000..4193c4ba3e --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/HugeCommitMessageTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.lib; + +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.storage.file.WindowCacheConfig; +import org.eclipse.jgit.storage.pack.PackConfig; +import org.junit.Test; + +public class HugeCommitMessageTest extends RepositoryTestCase { + + private static final int HUGE_SIZE = Math.max(15 * WindowCacheConfig.MB, + PackConfig.DEFAULT_BIG_FILE_THRESHOLD + WindowCacheConfig.MB); + // Larger than the 5MB fallback limit in RevWalk.getCachedBytes(RevObject + // obj, ObjectLoader ldr), and also larger than the default + // streamFileThreshold. + + @Test + public void testHugeCommitMessage() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("foo", "foo"); + git.add().addFilepattern("foo").call(); + WindowCacheConfig wc = new WindowCacheConfig(); + wc.setStreamFileThreshold(HUGE_SIZE + WindowCacheConfig.MB); + wc.install(); + RevCommit commit = git.commit() + .setMessage(insanelyHugeCommitMessage()).call(); + Ref master = db.findRef("master"); + List<Ref> actual = git.branchList().setContains(commit.getName()) + .call(); + assertTrue("Should be contained in branch master", + actual.contains(master)); + } + } + + private String insanelyHugeCommitMessage() { + final String oneLine = "012345678901234567890123456789012345678901234567890123456789\n"; + StringBuilder b = new StringBuilder(HUGE_SIZE + oneLine.length()); + // Give the message a real header; otherwise even writing the reflog + // message may run into troubles because RevCommit.getShortMessage() + // will return the whole message. + b.append("An insanely huge commit message\n\n"); + while (b.length() < HUGE_SIZE) { + b.append(oneLine); + } + return b.toString(); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java index 1ab36f0b62..531c918e9b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.lib; import static java.lang.Integer.valueOf; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.junit.JGitTestUtil.concat; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; import static org.eclipse.jgit.lib.Constants.OBJ_BAD; @@ -1560,7 +1560,7 @@ public class ObjectCheckerTest { StringBuilder b = new StringBuilder(); entry(b, "100644 A"); entry(b, "100644 a"); - byte[] data = b.toString().getBytes(CHARSET); + byte[] data = b.toString().getBytes(UTF_8); checker.setSafeForWindows(true); assertCorrupt("duplicate entry names", OBJ_TREE, data); assertSkipListAccepts(OBJ_TREE, data); @@ -1574,7 +1574,7 @@ public class ObjectCheckerTest { StringBuilder b = new StringBuilder(); entry(b, "100644 A"); entry(b, "100644 a"); - byte[] data = b.toString().getBytes(CHARSET); + byte[] data = b.toString().getBytes(UTF_8); checker.setSafeForMacOS(true); assertCorrupt("duplicate entry names", OBJ_TREE, data); assertSkipListAccepts(OBJ_TREE, data); @@ -1588,7 +1588,7 @@ public class ObjectCheckerTest { StringBuilder b = new StringBuilder(); entry(b, "100644 \u0065\u0301"); entry(b, "100644 \u00e9"); - byte[] data = b.toString().getBytes(CHARSET); + byte[] data = b.toString().getBytes(UTF_8); checker.setSafeForMacOS(true); assertCorrupt("duplicate entry names", OBJ_TREE, data); assertSkipListAccepts(OBJ_TREE, data); @@ -1602,7 +1602,7 @@ public class ObjectCheckerTest { StringBuilder b = new StringBuilder(); entry(b, "100644 A"); checker.setSafeForMacOS(true); - checker.checkTree(b.toString().getBytes(CHARSET)); + checker.checkTree(b.toString().getBytes(UTF_8)); } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java index 8d9ccab1bd..3542dfad2d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.lib; import static java.lang.Long.valueOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import java.io.File; import java.io.FileOutputStream; @@ -157,10 +158,13 @@ public class RacyGitTests extends RepositoryTestCase { // Remember the last modTime of index file. All modifications times of // further modification are translated to this value so it looks that // files have been modified in the same time slot as the index file - modTimes.add(Long.valueOf(db.getIndexFile().lastModified())); + long indexMod = db.getIndexFile().lastModified(); + modTimes.add(Long.valueOf(indexMod)); // modify one file - addToWorkDir("a", "a2"); + long aMod = addToWorkDir("a", "a2").lastModified(); + assumeTrue(aMod == indexMod); + // now update the index the index. 'a' has to be racily clean -- because // it's modification time is exactly the same as the previous index file // mod time. diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java index 2481e64997..a42027b584 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java @@ -58,7 +58,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; -import java.util.Map; +import java.util.Optional; import java.util.TreeSet; import org.eclipse.jgit.lib.Ref.Storage; @@ -148,17 +148,22 @@ public class RefTest extends SampleDataRepositoryTestCase { ObjectId r = db.resolve("refs/remotes/origin/HEAD"); assertEquals(masterId, r); - Map<String, Ref> allRefs = db.getAllRefs(); - Ref refHEAD = allRefs.get("refs/remotes/origin/HEAD"); - assertNotNull(refHEAD); - assertEquals(masterId, refHEAD.getObjectId()); - assertFalse(refHEAD.isPeeled()); - assertNull(refHEAD.getPeeledObjectId()); - - Ref refmaster = allRefs.get("refs/remotes/origin/master"); - assertEquals(masterId, refmaster.getObjectId()); - assertFalse(refmaster.isPeeled()); - assertNull(refmaster.getPeeledObjectId()); + List<Ref> allRefs = db.getRefDatabase().getRefs(); + Optional<Ref> refHEAD = allRefs.stream() + .filter(ref -> ref.getName().equals("refs/remotes/origin/HEAD")) + .findAny(); + assertTrue(refHEAD.isPresent()); + assertEquals(masterId, refHEAD.get().getObjectId()); + assertFalse(refHEAD.get().isPeeled()); + assertNull(refHEAD.get().getPeeledObjectId()); + + Optional<Ref> refmaster = allRefs.stream().filter( + ref -> ref.getName().equals("refs/remotes/origin/master")) + .findAny(); + assertTrue(refmaster.isPresent()); + assertEquals(masterId, refmaster.get().getObjectId()); + assertFalse(refmaster.get().isPeeled()); + assertNull(refmaster.get().getPeeledObjectId()); } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java index aaa08a9e31..a67c750dba 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java @@ -42,6 +42,8 @@ */ package org.eclipse.jgit.merge; +import static java.nio.charset.StandardCharsets.UTF_8; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -881,7 +883,7 @@ public class CrissCrossMergeTest extends RepositoryTestCase { StringBuilder result = new StringBuilder(); ObjectReader or = r.newObjectReader(); try (BufferedReader br = new BufferedReader( - new InputStreamReader(or.open(blobId).openStream()))) { + new InputStreamReader(or.open(blobId).openStream(), UTF_8))) { String line; boolean first = true; while ((line = br.readLine()) != null) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java index 58093a3729..8f12dd7b27 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.merge; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -60,6 +60,7 @@ import java.util.Map; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.MergeResult; import org.eclipse.jgit.api.MergeResult.MergeStatus; +import org.eclipse.jgit.api.RebaseResult; import org.eclipse.jgit.api.errors.CheckoutConflictException; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; @@ -428,6 +429,44 @@ public class MergerTest extends RepositoryTestCase { indexState(CONTENT)); } + @Theory + public void rebaseWithCrlfAutoCrlfTrue(MergeStrategy strategy) + throws IOException, GitAPIException { + Git git = Git.wrap(db); + db.getConfig().setString("core", null, "autocrlf", "true"); + db.getConfig().save(); + writeTrashFile("crlf.txt", "line 1\r\nline 2\r\nline 3\r\n"); + git.add().addFilepattern("crlf.txt").call(); + RevCommit first = git.commit().setMessage("base").call(); + + git.checkout().setCreateBranch(true).setStartPoint(first) + .setName("brancha").call(); + + File testFile = writeTrashFile("crlf.txt", + "line 1\r\nmodified line\r\nline 3\r\n"); + git.add().addFilepattern("crlf.txt").call(); + git.commit().setMessage("on brancha").call(); + + git.checkout().setName("master").call(); + File otherFile = writeTrashFile("otherfile.txt", "a line\r\n"); + git.add().addFilepattern("otherfile.txt").call(); + git.commit().setMessage("on master").call(); + + git.checkout().setName("brancha").call(); + checkFile(testFile, "line 1\r\nmodified line\r\nline 3\r\n"); + assertFalse(otherFile.exists()); + + RebaseResult rebaseResult = git.rebase().setStrategy(strategy) + .setUpstream(db.resolve("master")).call(); + assertEquals(RebaseResult.Status.OK, rebaseResult.getStatus()); + checkFile(testFile, "line 1\r\nmodified line\r\nline 3\r\n"); + checkFile(otherFile, "a line\r\n"); + assertEquals( + "[crlf.txt, mode:100644, content:line 1\nmodified line\nline 3\n]" + + "[otherfile.txt, mode:100644, content:a line\n]", + indexState(CONTENT)); + } + /** * Merging two equal subtrees when the index does not contain any file in * that subtree should lead to a merged state. @@ -754,7 +793,7 @@ public class MergerTest extends RepositoryTestCase { } binary[50] = '\0'; - writeTrashFile("file", new String(binary, CHARSET)); + writeTrashFile("file", new String(binary, UTF_8)); git.add().addFilepattern("file").call(); RevCommit first = git.commit().setMessage("added file").call(); @@ -762,7 +801,7 @@ public class MergerTest extends RepositoryTestCase { int idx = LINELEN * 1200 + 1; byte save = binary[idx]; binary[idx] = '@'; - writeTrashFile("file", new String(binary, CHARSET)); + writeTrashFile("file", new String(binary, UTF_8)); binary[idx] = save; git.add().addFilepattern("file").call(); @@ -771,7 +810,7 @@ public class MergerTest extends RepositoryTestCase { git.checkout().setCreateBranch(true).setStartPoint(first).setName("side").call(); binary[LINELEN * 1500 + 1] = '!'; - writeTrashFile("file", new String(binary, CHARSET)); + writeTrashFile("file", new String(binary, UTF_8)); git.add().addFilepattern("file").call(); RevCommit sideCommit = git.commit().setAll(true) .setMessage("modified file l 1500").call(); @@ -933,7 +972,7 @@ public class MergerTest extends RepositoryTestCase { merger.getMergeResults().get("file"); try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { fmt.formatMerge(out, merger.getMergeResults().get("file"), - "BASE", "OURS", "THEIRS", CHARSET.name()); + "BASE", "OURS", "THEIRS", UTF_8.name()); String expected = "<<<<<<< OURS\n" + "1master\n" + "=======\n" @@ -941,7 +980,7 @@ public class MergerTest extends RepositoryTestCase { + ">>>>>>> THEIRS\n" + "2\n" + "3"; - assertEquals(expected, new String(out.toByteArray(), CHARSET)); + assertEquals(expected, new String(out.toByteArray(), UTF_8)); } } } @@ -1328,6 +1367,7 @@ public class MergerTest extends RepositoryTestCase { if (obj == null) { return null; } - return new String(rw.getObjectReader().open(obj, OBJ_BLOB).getBytes(), CHARSET); + return new String(rw.getObjectReader().open(obj, OBJ_BLOB).getBytes(), + UTF_8); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/GetTextTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/GetTextTest.java index 7b5868a393..e383f36bca 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/GetTextTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/GetTextTest.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.patch; import static java.nio.charset.StandardCharsets.ISO_8859_1; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -83,7 +83,7 @@ public class GetTextTest { @Test public void testGetText_Convert() throws IOException { final Charset csOld = ISO_8859_1; - final Charset csNew = CHARSET; + final Charset csNew = UTF_8; final Patch p = parseTestPatchFile(); assertTrue(p.getErrors().isEmpty()); assertEquals(1, p.getFiles().size()); @@ -103,7 +103,7 @@ public class GetTextTest { @Test public void testGetText_DiffCc() throws IOException { final Charset csOld = ISO_8859_1; - final Charset csNew = CHARSET; + final Charset csNew = UTF_8; final Patch p = parseTestPatchFile(); assertTrue(p.getErrors().isEmpty()); assertEquals(1, p.getFiles().size()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java index cfefac3aa1..b814984935 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.revwalk; import static java.nio.charset.StandardCharsets.ISO_8859_1; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -114,7 +114,7 @@ public class RevCommitParseTest extends RepositoryTestCase { assertNull(c.getTree()); assertNull(c.parents); - c.parseCanonical(rw, body.toString().getBytes(CHARSET)); + c.parseCanonical(rw, body.toString().getBytes(UTF_8)); assertNotNull(c.getTree()); assertEquals(treeId, c.getTree().getId()); assertSame(rw.lookupTree(treeId), c.getTree()); @@ -148,7 +148,7 @@ public class RevCommitParseTest extends RepositoryTestCase { final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toString().getBytes(CHARSET)); + c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8)); return c; } @@ -161,7 +161,7 @@ public class RevCommitParseTest extends RepositoryTestCase { final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toString().getBytes(CHARSET)); + c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8)); assertEquals("", c.getFullMessage()); assertEquals("", c.getShortMessage()); @@ -176,7 +176,7 @@ public class RevCommitParseTest extends RepositoryTestCase { final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toString().getBytes(CHARSET)); + c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8)); assertEquals(new PersonIdent("", "a_u_thor@example.com", 1218123387000l, 7), c.getAuthorIdent()); assertEquals(new PersonIdent("", "", 1218123390000l, -5), c.getCommitterIdent()); @@ -185,18 +185,18 @@ public class RevCommitParseTest extends RepositoryTestCase { @Test public void testParse_implicit_UTF8_encoded() throws Exception { final ByteArrayOutputStream b = new ByteArrayOutputStream(); - b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(CHARSET)); - b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes(CHARSET)); - b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("\u304d\u308c\u3044\n".getBytes(CHARSET)); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8)); + b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes(UTF_8)); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id c.parseCanonical(new RevWalk(db), b.toByteArray()); - assertSame(Constants.CHARSET, c.getEncoding()); + assertSame(UTF_8, c.getEncoding()); assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n", c.getFullMessage()); @@ -205,18 +205,18 @@ public class RevCommitParseTest extends RepositoryTestCase { @Test public void testParse_implicit_mixed_encoded() throws Exception { final ByteArrayOutputStream b = new ByteArrayOutputStream(); - b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(CHARSET)); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8)); b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes(ISO_8859_1)); - b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("\u304d\u308c\u3044\n".getBytes(CHARSET)); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id c.parseCanonical(new RevWalk(db), b.toByteArray()); - assertSame(Constants.CHARSET, c.getEncoding()); + assertSame(UTF_8, c.getEncoding()); assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n", c.getFullMessage()); @@ -260,14 +260,14 @@ public class RevCommitParseTest extends RepositoryTestCase { @Test public void testParse_explicit_bad_encoded() throws Exception { final ByteArrayOutputStream b = new ByteArrayOutputStream(); - b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(CHARSET)); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8)); b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes(ISO_8859_1)); - b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes(CHARSET)); - b.write("encoding EUC-JP\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("\u304d\u308c\u3044\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("Hi\n".getBytes(CHARSET)); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes(UTF_8)); + b.write("encoding EUC-JP\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("Hi\n".getBytes(UTF_8)); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id c.parseCanonical(new RevWalk(db), b.toByteArray()); @@ -291,14 +291,14 @@ public class RevCommitParseTest extends RepositoryTestCase { @Test public void testParse_explicit_bad_encoded2() throws Exception { final ByteArrayOutputStream b = new ByteArrayOutputStream(); - b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(CHARSET)); - b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes(CHARSET)); - b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes(CHARSET)); - b.write("encoding ISO-8859-1\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("\u304d\u308c\u3044\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("Hi\n".getBytes(CHARSET)); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8)); + b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes(UTF_8)); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes(UTF_8)); + b.write("encoding ISO-8859-1\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("Hi\n".getBytes(UTF_8)); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id c.parseCanonical(new RevWalk(db), b.toByteArray()); @@ -313,13 +313,13 @@ public class RevCommitParseTest extends RepositoryTestCase { public void testParse_incorrectUtf8Name() throws Exception { ByteArrayOutputStream b = new ByteArrayOutputStream(); b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" - .getBytes(CHARSET)); - b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(CHARSET)); + .getBytes(UTF_8)); + b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8)); b.write("committer co <c@example.com> 1218123390 -0500\n" - .getBytes(CHARSET)); - b.write("encoding 'utf8'\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(CHARSET)); + .getBytes(UTF_8)); + b.write("encoding 'utf8'\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8)); RevCommit c = new RevCommit( id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); @@ -338,12 +338,12 @@ public class RevCommitParseTest extends RepositoryTestCase { @Test public void testParse_illegalEncoding() throws Exception { ByteArrayOutputStream b = new ByteArrayOutputStream(); - b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(CHARSET)); - b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(CHARSET)); - b.write("committer co <c@example.com> 1218123390 -0500\n".getBytes(CHARSET)); - b.write("encoding utf-8logoutputencoding=gbk\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("message\n".getBytes(CHARSET)); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8)); + b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8)); + b.write("committer co <c@example.com> 1218123390 -0500\n".getBytes(UTF_8)); + b.write("encoding utf-8logoutputencoding=gbk\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("message\n".getBytes(UTF_8)); RevCommit c = new RevCommit( id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); @@ -365,12 +365,12 @@ public class RevCommitParseTest extends RepositoryTestCase { @Test public void testParse_unsupportedEncoding() throws Exception { ByteArrayOutputStream b = new ByteArrayOutputStream(); - b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(CHARSET)); - b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(CHARSET)); - b.write("committer co <c@example.com> 1218123390 -0500\n".getBytes(CHARSET)); - b.write("encoding it_IT.UTF8\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("message\n".getBytes(CHARSET)); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8)); + b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8)); + b.write("committer co <c@example.com> 1218123390 -0500\n".getBytes(UTF_8)); + b.write("encoding it_IT.UTF8\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("message\n".getBytes(UTF_8)); RevCommit c = new RevCommit( id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); @@ -486,4 +486,36 @@ public class RevCommitParseTest extends RepositoryTestCase { private static ObjectId id(String str) { return ObjectId.fromString(str); } + + @Test + public void testParse_gpgSig() throws Exception { + String commit = "tree e3a1035abd2b319bb01e57d69b0ba6cab289297e\n" + + "parent 54e895b87c0768d2317a2b17062e3ad9f76a8105\n" + + "committer A U Thor <author@xample.com 1528968566 +0200\n" + + "gpgsig -----BEGIN PGP SIGNATURE-----\n" + + " \n" + + " wsBcBAABCAAQBQJbGB4pCRBK7hj4Ov3rIwAAdHIIAENrvz23867ZgqrmyPemBEZP\n" + + " U24B1Tlq/DWvce2buaxmbNQngKZ0pv2s8VMc11916WfTIC9EKvioatmpjduWvhqj\n" + + " znQTFyiMor30pyYsfrqFuQZvqBW01o8GEWqLg8zjf9Rf0R3LlOEw86aT8CdHRlm6\n" + + " wlb22xb8qoX4RB+LYfz7MhK5F+yLOPXZdJnAVbuyoMGRnDpwdzjL5Hj671+XJxN5\n" + + " SasRdhxkkfw/ZnHxaKEc4juMz8Nziz27elRwhOQqlTYoXNJnsV//wy5Losd7aKi1\n" + + " xXXyUpndEOmT0CIcKHrN/kbYoVL28OJaxoBuva3WYQaRrzEe3X02NMxZe9gkSqA=\n" + + " =TClh\n" + + " -----END PGP SIGNATURE-----\n" + + "some other header\n\n" + + "commit message"; + + final RevCommit c; + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), commit.getBytes(UTF_8)); + String gpgSig = new String(c.getRawGpgSignature(), UTF_8); + assertTrue(gpgSig.startsWith("-----BEGIN")); + assertTrue(gpgSig.endsWith("END PGP SIGNATURE-----")); + } + + @Test + public void testParse_NoGpgSig() throws Exception { + final RevCommit c = create("a message"); + assertNull(c.getRawGpgSignature()); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java index 8e389ae252..4969305de0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java @@ -144,13 +144,13 @@ public class RevObjectTest extends RevWalkTestCase { final RevCommit a = commit(); final RevFlag flag1 = rw.newFlag("flag1"); final RevFlag flag2 = rw.newFlag("flag2"); - assertEquals(0, a.flags); + assertEquals(RevWalk.PARSED, a.flags); a.add(flag1); - assertEquals(flag1.mask, a.flags); + assertEquals(RevWalk.PARSED | flag1.mask, a.flags); a.add(flag2); - assertEquals(flag1.mask | flag2.mask, a.flags); + assertEquals(RevWalk.PARSED | flag1.mask | flag2.mask, a.flags); } @Test @@ -162,10 +162,10 @@ public class RevObjectTest extends RevWalkTestCase { s.add(flag1); s.add(flag2); - assertEquals(0, a.flags); + assertEquals(RevWalk.PARSED, a.flags); a.add(s); - assertEquals(flag1.mask | flag2.mask, a.flags); + assertEquals(RevWalk.PARSED | flag1.mask | flag2.mask, a.flags); } @Test @@ -175,9 +175,9 @@ public class RevObjectTest extends RevWalkTestCase { final RevFlag flag2 = rw.newFlag("flag2"); a.add(flag1); a.add(flag2); - assertEquals(flag1.mask | flag2.mask, a.flags); + assertEquals(RevWalk.PARSED | flag1.mask | flag2.mask, a.flags); a.remove(flag2); - assertEquals(flag1.mask, a.flags); + assertEquals(RevWalk.PARSED | flag1.mask, a.flags); } @Test @@ -191,8 +191,8 @@ public class RevObjectTest extends RevWalkTestCase { s.add(flag2); a.add(flag3); a.add(s); - assertEquals(flag1.mask | flag2.mask | flag3.mask, a.flags); + assertEquals(RevWalk.PARSED | flag1.mask | flag2.mask | flag3.mask, a.flags); a.remove(s); - assertEquals(flag3.mask, a.flags); + assertEquals(RevWalk.PARSED | flag3.mask, a.flags); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java index e11cef7c92..1b45473066 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.revwalk; import static java.nio.charset.StandardCharsets.ISO_8859_1; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -98,7 +98,7 @@ public class RevTagParseTest extends RepositoryTestCase { assertNull(c.getObject()); assertNull(c.getTagName()); - c.parseCanonical(rw, b.toString().getBytes(CHARSET)); + c.parseCanonical(rw, b.toString().getBytes(UTF_8)); assertNotNull(c.getObject()); assertEquals(id, c.getObject().getId()); assertSame(rw.lookupAny(id, typeCode), c.getObject()); @@ -141,7 +141,7 @@ public class RevTagParseTest extends RepositoryTestCase { assertNull(c.getObject()); assertNull(c.getTagName()); - c.parseCanonical(rw, body.toString().getBytes(CHARSET)); + c.parseCanonical(rw, body.toString().getBytes(UTF_8)); assertNotNull(c.getObject()); assertEquals(treeId, c.getObject().getId()); assertSame(rw.lookupTree(treeId), c.getObject()); @@ -189,7 +189,7 @@ public class RevTagParseTest extends RepositoryTestCase { assertNull(c.getObject()); assertNull(c.getTagName()); - c.parseCanonical(rw, body.toString().getBytes(CHARSET)); + c.parseCanonical(rw, body.toString().getBytes(UTF_8)); assertNotNull(c.getObject()); assertEquals(treeId, c.getObject().getId()); assertSame(rw.lookupTree(treeId), c.getObject()); @@ -213,7 +213,7 @@ public class RevTagParseTest extends RepositoryTestCase { final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toString().getBytes(CHARSET)); + c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8)); return c; } @@ -221,17 +221,17 @@ public class RevTagParseTest extends RepositoryTestCase { public void testParse_implicit_UTF8_encoded() throws Exception { final ByteArrayOutputStream b = new ByteArrayOutputStream(); b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" - .getBytes(CHARSET)); - b.write("type tree\n".getBytes(CHARSET)); - b.write("tag v1.2.3.4.5\n".getBytes(CHARSET)); + .getBytes(UTF_8)); + b.write("type tree\n".getBytes(UTF_8)); + b.write("tag v1.2.3.4.5\n".getBytes(UTF_8)); b .write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" - .getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("\u304d\u308c\u3044\n".getBytes(CHARSET)); + .getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); c.parseCanonical(new RevWalk(db), b.toByteArray()); @@ -246,15 +246,15 @@ public class RevTagParseTest extends RepositoryTestCase { public void testParse_implicit_mixed_encoded() throws Exception { final ByteArrayOutputStream b = new ByteArrayOutputStream(); b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" - .getBytes(CHARSET)); - b.write("type tree\n".getBytes(CHARSET)); - b.write("tag v1.2.3.4.5\n".getBytes(CHARSET)); + .getBytes(UTF_8)); + b.write("type tree\n".getBytes(UTF_8)); + b.write("tag v1.2.3.4.5\n".getBytes(UTF_8)); b.write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" .getBytes(ISO_8859_1)); - b.write("\n".getBytes(CHARSET)); - b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("\u304d\u308c\u3044\n".getBytes(CHARSET)); + b.write("\n".getBytes(UTF_8)); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); c.parseCanonical(new RevWalk(db), b.toByteArray()); @@ -307,17 +307,17 @@ public class RevTagParseTest extends RepositoryTestCase { public void testParse_explicit_bad_encoded() throws Exception { final ByteArrayOutputStream b = new ByteArrayOutputStream(); b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" - .getBytes(CHARSET)); - b.write("type tree\n".getBytes(CHARSET)); - b.write("tag v1.2.3.4.5\n".getBytes(CHARSET)); + .getBytes(UTF_8)); + b.write("type tree\n".getBytes(UTF_8)); + b.write("tag v1.2.3.4.5\n".getBytes(UTF_8)); b .write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" .getBytes(ISO_8859_1)); - b.write("encoding EUC-JP\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("\u304d\u308c\u3044\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("Hi\n".getBytes(CHARSET)); + b.write("encoding EUC-JP\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("Hi\n".getBytes(UTF_8)); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); c.parseCanonical(new RevWalk(db), b.toByteArray()); @@ -342,17 +342,17 @@ public class RevTagParseTest extends RepositoryTestCase { public void testParse_explicit_bad_encoded2() throws Exception { final ByteArrayOutputStream b = new ByteArrayOutputStream(); b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" - .getBytes(CHARSET)); - b.write("type tree\n".getBytes(CHARSET)); - b.write("tag v1.2.3.4.5\n".getBytes(CHARSET)); + .getBytes(UTF_8)); + b.write("type tree\n".getBytes(UTF_8)); + b.write("tag v1.2.3.4.5\n".getBytes(UTF_8)); b .write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" - .getBytes(CHARSET)); - b.write("encoding ISO-8859-1\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("\u304d\u308c\u3044\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("Hi\n".getBytes(CHARSET)); + .getBytes(UTF_8)); + b.write("encoding ISO-8859-1\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("Hi\n".getBytes(UTF_8)); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); c.parseCanonical(new RevWalk(db), b.toByteArray()); @@ -365,13 +365,13 @@ public class RevTagParseTest extends RepositoryTestCase { @Test public void testParse_illegalEncoding() throws Exception { ByteArrayOutputStream b = new ByteArrayOutputStream(); - b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(CHARSET)); - b.write("type tree\n".getBytes(CHARSET)); - b.write("tag v1.0\n".getBytes(CHARSET)); - b.write("tagger t <t@example.com> 1218123387 +0700\n".getBytes(CHARSET)); - b.write("encoding utf-8logoutputencoding=gbk\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("message\n".getBytes(CHARSET)); + b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8)); + b.write("type tree\n".getBytes(UTF_8)); + b.write("tag v1.0\n".getBytes(UTF_8)); + b.write("tagger t <t@example.com> 1218123387 +0700\n".getBytes(UTF_8)); + b.write("encoding utf-8logoutputencoding=gbk\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("message\n".getBytes(UTF_8)); RevTag t = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); t.parseCanonical(new RevWalk(db), b.toByteArray()); @@ -384,13 +384,13 @@ public class RevTagParseTest extends RepositoryTestCase { @Test public void testParse_unsupportedEncoding() throws Exception { ByteArrayOutputStream b = new ByteArrayOutputStream(); - b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(CHARSET)); - b.write("type tree\n".getBytes(CHARSET)); - b.write("tag v1.0\n".getBytes(CHARSET)); - b.write("tagger t <t@example.com> 1218123387 +0700\n".getBytes(CHARSET)); - b.write("encoding it_IT.UTF8\n".getBytes(CHARSET)); - b.write("\n".getBytes(CHARSET)); - b.write("message\n".getBytes(CHARSET)); + b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8)); + b.write("type tree\n".getBytes(UTF_8)); + b.write("tag v1.0\n".getBytes(UTF_8)); + b.write("tagger t <t@example.com> 1218123387 +0700\n".getBytes(UTF_8)); + b.write("encoding it_IT.UTF8\n".getBytes(UTF_8)); + b.write("\n".getBytes(UTF_8)); + b.write("message\n".getBytes(UTF_8)); RevTag t = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); t.parseCanonical(new RevWalk(db), b.toByteArray()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCullTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCullTest.java index fb52828c5b..7984a37193 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCullTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCullTest.java @@ -85,7 +85,7 @@ public class RevWalkCullTest extends RevWalkTestCase { @Test public void testProperlyCullAllAncestors_LongHistory() throws Exception { - final RevCommit a = commit(); + RevCommit a = commit(); RevCommit b = commit(a); for (int i = 0; i < 24; i++) { b = commit(b); @@ -94,6 +94,12 @@ public class RevWalkCullTest extends RevWalkTestCase { } final RevCommit c = commit(b); + // TestRepository eagerly parses newly created objects. The current rw + // is caching that parsed state. To verify that RevWalk itself is lazy, + // set up a new one. + rw.close(); + rw = createRevWalk(); + RevCommit a2 = rw.lookupCommit(a); markStart(c); markUninteresting(b); assertCommit(c, rw.next()); @@ -102,6 +108,6 @@ public class RevWalkCullTest extends RevWalkTestCase { // We should have aborted before we got back so far that "a" // would be parsed. Thus, its parents shouldn't be allocated. // - assertNull(a.parents); + assertNull(a2.parents); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java index 6df36e78f1..7554d7a479 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkShallowTest.java @@ -58,138 +58,155 @@ public class RevWalkShallowTest extends RevWalkTestCase { @Test public void testDepth1() throws Exception { - final RevCommit a = commit(); - final RevCommit b = commit(a); - final RevCommit c = commit(b); - final RevCommit d = commit(c); + RevCommit[] commits = setupLinearChain(); - createShallowFile(d); + createShallowFile(commits[3]); + updateCommits(commits); - rw.reset(); - markStart(d); - assertCommit(d, rw.next()); + rw.markStart(commits[3]); + assertCommit(commits[3], rw.next()); assertNull(rw.next()); } @Test public void testDepth2() throws Exception { - final RevCommit a = commit(); - final RevCommit b = commit(a); - final RevCommit c = commit(b); - final RevCommit d = commit(c); + RevCommit[] commits = setupLinearChain(); - createShallowFile(c); + createShallowFile(commits[2]); + updateCommits(commits); - rw.reset(); - markStart(d); - assertCommit(d, rw.next()); - assertCommit(c, rw.next()); + rw.markStart(commits[3]); + assertCommit(commits[3], rw.next()); + assertCommit(commits[2], rw.next()); assertNull(rw.next()); } @Test public void testDepth3() throws Exception { - final RevCommit a = commit(); - final RevCommit b = commit(a); - final RevCommit c = commit(b); - final RevCommit d = commit(c); + RevCommit[] commits = setupLinearChain(); - createShallowFile(b); + createShallowFile(commits[1]); + updateCommits(commits); - rw.reset(); - markStart(d); - assertCommit(d, rw.next()); - assertCommit(c, rw.next()); - assertCommit(b, rw.next()); + rw.markStart(commits[3]); + assertCommit(commits[3], rw.next()); + assertCommit(commits[2], rw.next()); + assertCommit(commits[1], rw.next()); assertNull(rw.next()); } @Test - public void testMergeCommitOneParentShallow() throws Exception { - final RevCommit a = commit(); - final RevCommit b = commit(a); - final RevCommit c = commit(b); - final RevCommit d = commit(b); - final RevCommit e = commit(d); - final RevCommit merge = commit(c, e); - - createShallowFile(e); - - rw.reset(); - markStart(merge); - assertCommit(merge, rw.next()); - assertCommit(e, rw.next()); - assertCommit(c, rw.next()); - assertCommit(b, rw.next()); - assertCommit(a, rw.next()); + public void testObjectDirectorySnapshot() throws Exception { + RevCommit[] commits = setupLinearChain(); + + createShallowFile(commits[3]); + updateCommits(commits); + + markStart(commits[3]); + assertCommit(commits[3], rw.next()); assertNull(rw.next()); - } - @Test - public void testMergeCommitEntirelyShallow() throws Exception { - final RevCommit a = commit(); - final RevCommit b = commit(a); - final RevCommit c = commit(b); - final RevCommit d = commit(b); - final RevCommit e = commit(d); - final RevCommit merge = commit(c, e); - - createShallowFile(c, e); - - rw.reset(); - markStart(merge); - assertCommit(merge, rw.next()); - assertCommit(e, rw.next()); - assertCommit(c, rw.next()); + createShallowFile(commits[2]); + updateCommits(commits); + + markStart(commits[3]); + assertCommit(commits[3], rw.next()); + assertCommit(commits[2], rw.next()); assertNull(rw.next()); } + private RevCommit[] setupLinearChain() throws Exception { + RevCommit[] commits = new RevCommit[4]; + RevCommit parent = null; + for (int i = 0; i < commits.length; i++) { + commits[i] = parent != null ? commit(parent) : commit(); + parent = commits[i]; + } + return commits; + } + @Test - public void testObjectDirectorySnapshot() throws Exception { - RevCommit a = commit(); - RevCommit b = commit(a); - RevCommit c = commit(b); - RevCommit d = commit(c); + public void testMergeCommitOneParentShallow() throws Exception { + RevCommit[] commits = setupMergeChain(); - createShallowFile(d); + createShallowFile(commits[4]); + updateCommits(commits); - rw.reset(); - markStart(d); - assertCommit(d, rw.next()); + markStart(commits[5]); + assertCommit(commits[5], rw.next()); + assertCommit(commits[4], rw.next()); + assertCommit(commits[2], rw.next()); + assertCommit(commits[1], rw.next()); + assertCommit(commits[0], rw.next()); assertNull(rw.next()); + } - rw = createRevWalk(); - a = rw.lookupCommit(a); - b = rw.lookupCommit(b); - c = rw.lookupCommit(c); - d = rw.lookupCommit(d); - - rw.reset(); - markStart(d); - assertCommit(d, rw.next()); - assertNull(rw.next()); + @Test + public void testMergeCommitEntirelyShallow() throws Exception { + RevCommit[] commits = setupMergeChain(); - createShallowFile(c); + createShallowFile(commits[2], commits[4]); + updateCommits(commits); - rw = createRevWalk(); - a = rw.lookupCommit(a); - b = rw.lookupCommit(b); - c = rw.lookupCommit(c); - d = rw.lookupCommit(d); - - rw.reset(); - markStart(d); - assertCommit(d, rw.next()); - assertCommit(c, rw.next()); + markStart(commits[5]); + assertCommit(commits[5], rw.next()); + assertCommit(commits[4], rw.next()); + assertCommit(commits[2], rw.next()); assertNull(rw.next()); } + private RevCommit[] setupMergeChain() throws Exception { + /*- + * Create a history like this, diverging at 1 and merging at 5: + * + * ---o--o commits 3,4 + * / \ + * o--o--o------o commits 0,1,2,5 + */ + RevCommit[] commits = new RevCommit[6]; + commits[0] = commit(); + commits[1] = commit(commits[0]); + commits[2] = commit(commits[1]); + commits[3] = commit(commits[1]); + commits[4] = commit(commits[3]); + commits[5] = commit(commits[2], commits[4]); + return commits; + } + + private void updateCommits(RevCommit[] commits) { + // Relookup commits using the new RevWalk + for (int i = 0; i < commits.length; i++) { + commits[i] = rw.lookupCommit(commits[i].getId()); + } + } + private void createShallowFile(ObjectId... shallowCommits) throws IOException { - final StringBuilder builder = new StringBuilder(); - for (ObjectId commit : shallowCommits) + // Reset the RevWalk since the new shallow file invalidates the existing + // RevWalk's shallow state. + rw.close(); + rw = createRevWalk(); + StringBuilder builder = new StringBuilder(); + for (ObjectId commit : shallowCommits) { builder.append(commit.getName() + "\n"); + } JGitTestUtil.write(new File(db.getDirectory(), "shallow"), builder.toString()); } + + @Test + public void testShallowCommitParse() throws Exception { + RevCommit a = commit(); + RevCommit b = commit(a); + + createShallowFile(b); + + rw.close(); + rw = createRevWalk(); + b = rw.parseCommit(b); + + markStart(b); + assertCommit(b, rw.next()); + assertNull(rw.next()); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java index a26ae10af3..cb92a955bc 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkUtilsReachableTest.java @@ -115,7 +115,7 @@ public class RevWalkUtilsReachableTest extends RevWalkTestCase { } private void assertContains(RevCommit commit, Collection<Ref> refsThatShouldContainCommit) throws Exception { - Collection<Ref> allRefs = db.getAllRefs().values(); + Collection<Ref> allRefs = db.getRefDatabase().getRefs(); Collection<Ref> sortedRefs = RefComparator.sort(allRefs); List<Ref> actual = RevWalkUtils.findBranchesReachableFrom(commit, rw, sortedRefs); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java index 0dea5ce97b..7f0d60295c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileBasedConfigTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.storage.file; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.util.FileUtils.pathToString; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -105,7 +105,7 @@ public class FileBasedConfigTest { @Test public void testUTF8withoutBOM() throws IOException, ConfigInvalidException { - final File file = createFile(CONTENT1.getBytes(CHARSET)); + final File file = createFile(CONTENT1.getBytes(UTF_8)); final FileBasedConfig config = new FileBasedConfig(file, FS.DETECTED); config.load(); assertEquals(ALICE, config.getString(USER, null, NAME)); @@ -121,7 +121,7 @@ public class FileBasedConfigTest { bos1.write(0xEF); bos1.write(0xBB); bos1.write(0xBF); - bos1.write(CONTENT1.getBytes(CHARSET)); + bos1.write(CONTENT1.getBytes(UTF_8)); final File file = createFile(bos1.toByteArray()); final FileBasedConfig config = new FileBasedConfig(file, FS.DETECTED); @@ -135,7 +135,7 @@ public class FileBasedConfigTest { bos2.write(0xEF); bos2.write(0xBB); bos2.write(0xBF); - bos2.write(CONTENT2.getBytes(CHARSET)); + bos2.write(CONTENT2.getBytes(UTF_8)); assertArrayEquals(bos2.toByteArray(), IO.readFully(file)); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java index 57809734c3..1ff64a2e28 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java @@ -136,7 +136,49 @@ public class SubmoduleAddTest extends RepositoryTestCase { } SubmoduleWalk generator = SubmoduleWalk.forIndex(db); + generator.loadModulesConfig(); assertTrue(generator.next()); + assertEquals(path, generator.getModuleName()); + assertEquals(path, generator.getPath()); + assertEquals(commit, generator.getObjectId()); + assertEquals(uri, generator.getModulesUrl()); + assertEquals(path, generator.getModulesPath()); + assertEquals(uri, generator.getConfigUrl()); + try (Repository subModRepo = generator.getRepository()) { + assertNotNull(subModRepo); + assertEquals(subCommit, commit); + } + + Status status = Git.wrap(db).status().call(); + assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES)); + assertTrue(status.getAdded().contains(path)); + } + } + + @Test + public void addSubmoduleWithName() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("file.txt", "content"); + git.add().addFilepattern("file.txt").call(); + RevCommit commit = git.commit().setMessage("create file").call(); + + SubmoduleAddCommand command = new SubmoduleAddCommand(db); + String name = "testsub"; + command.setName(name); + String path = "sub"; + command.setPath(path); + String uri = db.getDirectory().toURI().toString(); + command.setURI(uri); + ObjectId subCommit; + try (Repository repo = command.call()) { + assertNotNull(repo); + subCommit = repo.resolve(Constants.HEAD); + } + + SubmoduleWalk generator = SubmoduleWalk.forIndex(db); + generator.loadModulesConfig(); + assertTrue(generator.next()); + assertEquals(name, generator.getModuleName()); assertEquals(path, generator.getPath()); assertEquals(commit, generator.getObjectId()); assertEquals(uri, generator.getModulesUrl()); @@ -187,16 +229,13 @@ public class SubmoduleAddTest extends RepositoryTestCase { public void addSubmoduleWithInvalidPath() throws Exception { SubmoduleAddCommand command = new SubmoduleAddCommand(db); command.setPath("-invalid-path"); - // TODO(ms) set name to a valid value in 5.1.0 and adapt expected - // message below + command.setName("sub"); command.setURI("http://example.com/repo/x.git"); try { command.call().close(); fail("Exception not thrown"); } catch (IllegalArgumentException e) { - // TODO(ms) should check for submodule path, but can't set name - // before 5.1.0 - assertEquals("Invalid submodule name '-invalid-path'", + assertEquals("Invalid submodule path '-invalid-path'", e.getMessage()); } } @@ -299,4 +338,18 @@ public class SubmoduleAddTest extends RepositoryTestCase { ConfigConstants.CONFIG_KEY_URL)); } } + + @Test + public void denySubmoduleWithDotDot() throws Exception { + SubmoduleAddCommand command = new SubmoduleAddCommand(db); + command.setName("dir/../"); + command.setPath("sub"); + command.setURI(db.getDirectory().toURI().toString()); + try { + command.call(); + fail(); + } catch (IllegalArgumentException e) { + // Expected + } + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java index df4b96398f..815ce9b350 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java @@ -136,10 +136,12 @@ public class SubmoduleDeinitTest extends RepositoryTestCase { generator.next(); //want to create a commit inside the repo... - Repository submoduleLocalRepo = generator.getRepository(); - JGitTestUtil.writeTrashFile(submoduleLocalRepo, "file.txt", "new data"); - Git.wrap(submoduleLocalRepo).commit().setAll(true).setMessage("local commit").call(); - + try (Repository submoduleLocalRepo = generator.getRepository()) { + JGitTestUtil.writeTrashFile(submoduleLocalRepo, "file.txt", + "new data"); + Git.wrap(submoduleLocalRepo).commit().setAll(true) + .setMessage("local commit").call(); + } SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub")); assertEquals(path, result.getPath()); assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java index d30ac840a6..7b31bfa3ad 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -199,7 +199,8 @@ public class BundleWriterTest extends SampleDataRepositoryTestCase { Ref ref = repo.exactRef(refName); assertNotNull(ref); assertEquals(id, ref.getObjectId()); - assertEquals(data, new String(repo.open(id, OBJ_BLOB).getBytes(), CHARSET)); + assertEquals(data, + new String(repo.open(id, OBJ_BLOB).getBytes(), UTF_8)); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/NetRCTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/NetRCTest.java index 4e5d56acb2..2a4e492e3d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/NetRCTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/NetRCTest.java @@ -42,7 +42,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -76,7 +76,7 @@ public class NetRCTest extends RepositoryTestCase { private void config(String data) throws IOException { try (OutputStreamWriter fw = new OutputStreamWriter( - new FileOutputStream(configFile), CHARSET)) { + new FileOutputStream(configFile), UTF_8)) { fw.write(data); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java index abf80ecd4d..19fcbfd7a2 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -94,7 +94,7 @@ public class OpenSshConfigTest extends RepositoryTestCase { long lastMtime = configFile.lastModified(); do { try (final OutputStreamWriter fw = new OutputStreamWriter( - new FileOutputStream(configFile), CHARSET)) { + new FileOutputStream(configFile), UTF_8)) { fw.write(data); } } while (lastMtime == configFile.lastModified()); 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 new file mode 100644 index 0000000000..4d1150844c --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2018, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.transport; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.hasItems; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.jgit.errors.PackProtocolException; +import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; +import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.revwalk.RevCommit; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ProtocolV2ParserTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private TestRepository<InMemoryRepository> testRepo; + + @Before + public void setUp() throws Exception { + testRepo = new TestRepository<>(newRepo("protocol-v2-parser-test")); + } + + private static InMemoryRepository newRepo(String name) { + return new InMemoryRepository(new DfsRepositoryDescription(name)); + } + + private static class ConfigBuilder { + + private boolean allowRefInWant; + + private boolean allowFilter; + + private ConfigBuilder() { + } + + static ConfigBuilder start() { + return new ConfigBuilder(); + } + + static TransferConfig getDefault() { + return start().done(); + } + + ConfigBuilder allowRefInWant() { + allowRefInWant = true; + return this; + } + + ConfigBuilder allowFilter() { + allowFilter = true; + return this; + } + + TransferConfig done() { + Config rc = new Config(); + rc.setBoolean("uploadpack", null, "allowrefinwant", allowRefInWant); + rc.setBoolean("uploadpack", null, "allowfilter", allowFilter); + return new TransferConfig(rc); + } + } + + /* + * Convert the input lines to the PacketLine that the parser reads. + */ + private static PacketLineIn formatAsPacketLine(String... inputLines) + throws IOException { + ByteArrayOutputStream send = new ByteArrayOutputStream(); + PacketLineOut pckOut = new PacketLineOut(send); + for (String line : inputLines) { + if (line == PacketLineIn.END) { + pckOut.end(); + } else if (line == PacketLineIn.DELIM) { + pckOut.writeDelim(); + } else { + pckOut.writeString(line); + } + } + + return new PacketLineIn(new ByteArrayInputStream(send.toByteArray())); + } + + private static List<String> objIdsAsStrings(Collection<ObjectId> objIds) { + // TODO(ifrade) Translate this to a matcher, so it would read as + // assertThat(req.wantsIds(), hasObjectIds("...", "...")) + return objIds.stream().map(ObjectId::name).collect(Collectors.toList()); + } + + /* + * Succesful fetch with the basic core commands of the protocol. + */ + @Test + public void testFetchBasicArguments() + throws PackProtocolException, IOException { + PacketLineIn pckIn = formatAsPacketLine( + PacketLineIn.DELIM, + "thin-pack", "no-progress", "include-tag", "ofs-delta", + "want 4624442d68ee402a94364191085b77137618633e", + "want f900c8326a43303685c46b279b9f70411bff1a4b", + "have 554f6e41067b9e3e565b6988a8294fac1cb78f4b", + "have abc760ab9ad72f08209943251b36cb886a578f87", "done", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.getDefault()); + FetchV2Request request = parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + assertTrue(request.getOptions() + .contains(GitProtocolConstants.OPTION_THIN_PACK)); + assertTrue(request.getOptions() + .contains(GitProtocolConstants.OPTION_NO_PROGRESS)); + assertTrue(request.getOptions() + .contains(GitProtocolConstants.OPTION_INCLUDE_TAG)); + assertTrue(request.getOptions() + .contains(GitProtocolConstants.CAPABILITY_OFS_DELTA)); + assertThat(objIdsAsStrings(request.getWantsIds()), + hasItems("4624442d68ee402a94364191085b77137618633e", + "f900c8326a43303685c46b279b9f70411bff1a4b")); + assertThat(objIdsAsStrings(request.getPeerHas()), + hasItems("554f6e41067b9e3e565b6988a8294fac1cb78f4b", + "abc760ab9ad72f08209943251b36cb886a578f87")); + assertTrue(request.getWantedRefs().isEmpty()); + assertTrue(request.wasDoneReceived()); + } + + @Test + public void testFetchWithShallow_deepen() throws IOException { + PacketLineIn pckIn = formatAsPacketLine( + PacketLineIn.DELIM, + "deepen 15", + "deepen-relative", + "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", + "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.getDefault()); + FetchV2Request request = parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + assertThat(objIdsAsStrings(request.getClientShallowCommits()), + hasItems("28274d02c489f4c7e68153056e9061a46f62d7a0", + "145e683b229dcab9d0e2ccb01b386f9ecc17d29d")); + assertTrue(request.getDeepenNotRefs().isEmpty()); + assertEquals(15, request.getDepth()); + assertTrue(request.getOptions() + .contains(GitProtocolConstants.OPTION_DEEPEN_RELATIVE)); + } + + @Test + public void testFetchWithShallow_deepenNot() throws IOException { + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", + "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", + "deepen-not a08595f76159b09d57553e37a5123f1091bb13e7", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.getDefault()); + FetchV2Request request = parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + assertThat(objIdsAsStrings(request.getClientShallowCommits()), + hasItems("28274d02c489f4c7e68153056e9061a46f62d7a0", + "145e683b229dcab9d0e2ccb01b386f9ecc17d29d")); + assertThat(request.getDeepenNotRefs(), + hasItems("a08595f76159b09d57553e37a5123f1091bb13e7")); + } + + @Test + public void testFetchWithShallow_deepenSince() throws IOException { + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", + "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", + "deepen-since 123123123", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.getDefault()); + FetchV2Request request = parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + assertThat(objIdsAsStrings(request.getClientShallowCommits()), + hasItems("28274d02c489f4c7e68153056e9061a46f62d7a0", + "145e683b229dcab9d0e2ccb01b386f9ecc17d29d")); + assertEquals(123123123, request.getDeepenSince()); + } + + @Test + public void testFetchWithNoneFilter() throws IOException { + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "filter blob:none", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.start().allowFilter().done()); + FetchV2Request request = parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + assertEquals(0, request.getFilterBlobLimit()); + } + + @Test + public void testFetchWithBlobSizeFilter() throws IOException { + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "filter blob:limit=15", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.start().allowFilter().done()); + FetchV2Request request = parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + assertEquals(15, request.getFilterBlobLimit()); + } + + @Test + public void testFetchMustNotHaveMultipleFilters() throws IOException { + thrown.expect(PackProtocolException.class); + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "filter blob:none", + "filter blob:limit=12", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.start().allowFilter().done()); + FetchV2Request request = parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + assertEquals(0, request.getFilterBlobLimit()); + } + + @Test + public void testFetchFilterWithoutAllowFilter() throws IOException { + thrown.expect(PackProtocolException.class); + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "filter blob:limit=12", PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.getDefault()); + parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + } + + @Test + public void testFetchWithRefInWant() throws Exception { + RevCommit one = testRepo.commit().message("1").create(); + RevCommit two = testRepo.commit().message("2").create(); + testRepo.update("branchA", one); + testRepo.update("branchB", two); + + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "want e4980cdc48cfa1301493ca94eb70523f6788b819", + "want-ref refs/heads/branchA", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.start().allowRefInWant().done()); + + + FetchV2Request request = parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + assertEquals(1, request.getWantedRefs().size()); + assertThat(request.getWantedRefs().keySet(), + hasItems("refs/heads/branchA")); + assertEquals(2, request.getWantsIds().size()); + assertThat(objIdsAsStrings(request.getWantsIds()), + hasItems("e4980cdc48cfa1301493ca94eb70523f6788b819", + one.getName())); + } + + @Test + public void testFetchWithRefInWantUnknownRef() throws Exception { + thrown.expect(PackProtocolException.class); + thrown.expectMessage(containsString("refs/heads/branchC")); + + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + "want e4980cdc48cfa1301493ca94eb70523f6788b819", + "want-ref refs/heads/branchC", + PacketLineIn.END); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.start().allowRefInWant().done()); + + RevCommit one = testRepo.commit().message("1").create(); + RevCommit two = testRepo.commit().message("2").create(); + testRepo.update("branchA", one); + testRepo.update("branchB", two); + + parser.parseFetchRequest(pckIn, + testRepo.getRepository().getRefDatabase()); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java index 0ffbe65786..c959f6c497 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java @@ -259,6 +259,7 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas try (TransportLocal t = newTransportLocalWithStrictValidation()) { t.setPushThin(true); r = t.push(PM, Collections.singleton(u)); + dst.close(); } assertNotNull("have result", r); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java index 86c92bb528..953c9fc30a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java @@ -77,6 +77,7 @@ public class TestProtocolTest { "+refs/heads/master:refs/heads/master"); private static final int HAVES_PER_ROUND = 32; + private static final int MAX_HAVES = 256; private static class User { private final String name; @@ -187,7 +188,7 @@ public class TestProtocolTest { } @Test - public void testMinimalNegotiation() throws Exception { + public void testMaxHaves() throws Exception { TestProtocol<User> proto = registerDefault(); URIish uri = proto.register(new User("user"), remote.getRepository()); @@ -200,28 +201,13 @@ public class TestProtocolTest { RevCommit master = remote.branch("master").commit() .add("readme.txt", "unique commit").create(); - TestProtocol.setFetchConfig(new FetchConfig(true, true)); + TestProtocol.setFetchConfig(new FetchConfig(true, MAX_HAVES)); try (Git git = new Git(local.getRepository())) { assertNull(local.getRepository().exactRef("refs/heads/master")); git.fetch().setRemote(uri.toString()).setRefSpecs(MASTER).call(); assertEquals(master, local.getRepository() .exactRef("refs/heads/master").getObjectId()); - assertTrue(havesCount <= 2 * HAVES_PER_ROUND); - - // Update the remote master and add local branches for 5 more rounds - // of negotiation, where the local branch commits have newer - // timestamps. Negotiation should send 5 rounds for those newer - // branches before getting to the round that sends its stale version - // of master. - master = remote.branch("master").commit().parent(master).create(); - local.tick(2 * HAVES_PER_ROUND); - for (int i = 0; i < 5 * HAVES_PER_ROUND; i++) { - local.branch("local-" + i).commit().create(); - } - git.fetch().setRemote(uri.toString()).setRefSpecs(MASTER).call(); - assertEquals(master, local.getRepository() - .exactRef("refs/heads/master").getObjectId()); - assertEquals(6 * HAVES_PER_ROUND, havesCount); + assertTrue(havesCount <= MAX_HAVES); } } 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 ef083da183..317ac32e6d 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 @@ -1,20 +1,25 @@ package org.eclipse.jgit.transport; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.theInstance; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringWriter; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector; @@ -29,8 +34,8 @@ import org.eclipse.jgit.lib.Sets; import org.eclipse.jgit.lib.TextProgressMonitor; import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevTag; +import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.transport.UploadPack.RequestPolicy; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; @@ -227,6 +232,44 @@ public class UploadPackTest { } @Test + public void testFetchExplicitBlobWithFilter() throws Exception { + InMemoryRepository server2 = newRepo("server2"); + TestRepository<InMemoryRepository> remote2 = + new TestRepository<>(server2); + RevBlob blob1 = remote2.blob("foobar"); + RevBlob blob2 = remote2.blob("fooba"); + RevTree tree = remote2.tree(remote2.file("1", blob1), + remote2.file("2", blob2)); + RevCommit commit = remote2.commit(tree); + remote2.update("master", commit); + remote2.update("a_blob", blob1); + + server2.getConfig().setBoolean("uploadpack", null, "allowfilter", true); + + testProtocol = new TestProtocol<>( + new UploadPackFactory<Object>() { + @Override + public UploadPack create(Object req, Repository db) + throws ServiceNotEnabledException, + ServiceNotAuthorizedException { + UploadPack up = new UploadPack(db); + return up; + } + }, null); + uri = testProtocol.register(ctx, server2); + + try (Transport tn = testProtocol.open(uri, client, "server2")) { + tn.setFilterBlobLimit(0); + tn.fetch(NullProgressMonitor.INSTANCE, Arrays.asList( + new RefSpec(commit.name()), + new RefSpec(blob1.name()))); + assertTrue(client.hasObject(tree.toObjectId())); + assertTrue(client.hasObject(blob1.toObjectId())); + assertFalse(client.hasObject(blob2.toObjectId())); + } + } + + @Test public void testFetchWithBlobLimitFilter() throws Exception { InMemoryRepository server2 = newRepo("server2"); TestRepository<InMemoryRepository> remote2 = @@ -262,6 +305,47 @@ public class UploadPackTest { } @Test + public void testFetchExplicitBlobWithFilterAndBitmaps() throws Exception { + InMemoryRepository server2 = newRepo("server2"); + TestRepository<InMemoryRepository> remote2 = + new TestRepository<>(server2); + RevBlob blob1 = remote2.blob("foobar"); + RevBlob blob2 = remote2.blob("fooba"); + RevTree tree = remote2.tree(remote2.file("1", blob1), + remote2.file("2", blob2)); + RevCommit commit = remote2.commit(tree); + remote2.update("master", commit); + remote2.update("a_blob", blob1); + + server2.getConfig().setBoolean("uploadpack", null, "allowfilter", true); + + // generate bitmaps + new DfsGarbageCollector(server2).pack(null); + server2.scanForRepoChanges(); + + testProtocol = new TestProtocol<>( + new UploadPackFactory<Object>() { + @Override + public UploadPack create(Object req, Repository db) + throws ServiceNotEnabledException, + ServiceNotAuthorizedException { + UploadPack up = new UploadPack(db); + return up; + } + }, null); + uri = testProtocol.register(ctx, server2); + + try (Transport tn = testProtocol.open(uri, client, "server2")) { + tn.setFilterBlobLimit(0); + tn.fetch(NullProgressMonitor.INSTANCE, Arrays.asList( + new RefSpec(commit.name()), + new RefSpec(blob1.name()))); + assertTrue(client.hasObject(blob1.toObjectId())); + assertFalse(client.hasObject(blob2.toObjectId())); + } + } + + @Test public void testFetchWithBlobLimitFilterAndBitmaps() throws Exception { InMemoryRepository server2 = newRepo("server2"); TestRepository<InMemoryRepository> remote2 = @@ -340,7 +424,8 @@ public class UploadPackTest { * and returns UploadPack's output stream. */ private ByteArrayInputStream uploadPackV2Setup(RequestPolicy requestPolicy, - RefFilter refFilter, String... inputLines) throws Exception { + RefFilter refFilter, ProtocolV2Hook hook, String... inputLines) + throws Exception { ByteArrayOutputStream send = new ByteArrayOutputStream(); PacketLineOut pckOut = new PacketLineOut(send); @@ -361,6 +446,9 @@ public class UploadPackTest { if (refFilter != null) up.setRefFilter(refFilter); up.setExtraParameters(Sets.of("version=2")); + if (hook != null) { + up.setProtocolV2Hook(hook); + } ByteArrayOutputStream recv = new ByteArrayOutputStream(); up.upload(new ByteArrayInputStream(send.toByteArray()), recv, null); @@ -374,9 +462,10 @@ public class UploadPackTest { * advertisement by the server. */ private ByteArrayInputStream uploadPackV2(RequestPolicy requestPolicy, - RefFilter refFilter, String... inputLines) throws Exception { + RefFilter refFilter, ProtocolV2Hook hook, String... inputLines) + throws Exception { ByteArrayInputStream recvStream = - uploadPackV2Setup(requestPolicy, refFilter, inputLines); + uploadPackV2Setup(requestPolicy, refFilter, hook, inputLines); PacketLineIn pckIn = new PacketLineIn(recvStream); // drain capabilities @@ -387,15 +476,33 @@ public class UploadPackTest { } private ByteArrayInputStream uploadPackV2(String... inputLines) throws Exception { - return uploadPackV2(null, null, inputLines); + return uploadPackV2(null, null, null, inputLines); + } + + private static class TestV2Hook implements ProtocolV2Hook { + private CapabilitiesV2Request capabilitiesRequest; + + private LsRefsV2Request lsRefsRequest; + + @Override + public void onCapabilities(CapabilitiesV2Request req) { + capabilitiesRequest = req; + } + + @Override + public void onLsRefs(LsRefsV2Request req) { + lsRefsRequest = req; + } } @Test public void testV2Capabilities() throws Exception { + TestV2Hook hook = new TestV2Hook(); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, hook, PacketLineIn.END); PacketLineIn pckIn = new PacketLineIn(recvStream); + assertThat(hook.capabilitiesRequest, notNullValue()); assertThat(pckIn.readString(), is("version 2")); assertThat( Arrays.asList(pckIn.readString(), pckIn.readString()), @@ -413,7 +520,7 @@ public class UploadPackTest { public void testV2CapabilitiesAllowFilter() throws Exception { server.getConfig().setBoolean("uploadpack", null, "allowfilter", true); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.END); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -426,12 +533,56 @@ public class UploadPackTest { } @Test - @SuppressWarnings("boxing") + public void testV2CapabilitiesRefInWant() throws Exception { + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); + ByteArrayInputStream recvStream = + uploadPackV2Setup(null, null, null, PacketLineIn.END); + PacketLineIn pckIn = new PacketLineIn(recvStream); + + assertThat(pckIn.readString(), is("version 2")); + assertThat( + Arrays.asList(pckIn.readString(), pckIn.readString()), + // TODO(jonathantanmy) This check overspecifies the + // order of the capabilities of "fetch". + hasItems("ls-refs", "fetch=ref-in-want shallow")); + assertTrue(pckIn.readString() == PacketLineIn.END); + } + + @Test + public void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Exception { + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", false); + ByteArrayInputStream recvStream = + uploadPackV2Setup(null, null, null, PacketLineIn.END); + PacketLineIn pckIn = new PacketLineIn(recvStream); + + assertThat(pckIn.readString(), is("version 2")); + assertThat( + Arrays.asList(pckIn.readString(), pckIn.readString()), + hasItems("ls-refs", "fetch=shallow")); + assertTrue(pckIn.readString() == PacketLineIn.END); + } + + @Test + public void testV2CapabilitiesRefInWantNotAdvertisedIfAdvertisingForbidden() throws Exception { + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); + server.getConfig().setBoolean("uploadpack", null, "advertiserefinwant", false); + ByteArrayInputStream recvStream = + uploadPackV2Setup(null, null, null, PacketLineIn.END); + PacketLineIn pckIn = new PacketLineIn(recvStream); + + assertThat(pckIn.readString(), is("version 2")); + assertThat( + Arrays.asList(pckIn.readString(), pckIn.readString()), + hasItems("ls-refs", "fetch=shallow")); + assertTrue(pckIn.readString() == PacketLineIn.END); + } + + @Test public void testV2EmptyRequest() throws Exception { ByteArrayInputStream recvStream = uploadPackV2(PacketLineIn.END); // Verify that there is nothing more after the capability // advertisement. - assertThat(recvStream.available(), is(0)); + assertEquals(0, recvStream.available()); } @Test @@ -442,9 +593,12 @@ public class UploadPackTest { RevTag tag = remote.tag("tag", tip); remote.update("refs/tags/tag", tag); - ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", PacketLineIn.END); + TestV2Hook hook = new TestV2Hook(); + ByteArrayInputStream recvStream = uploadPackV2(null, null, hook, + "command=ls-refs\n", PacketLineIn.END); PacketLineIn pckIn = new PacketLineIn(recvStream); + assertThat(hook.lsRefsRequest, notNullValue()); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag")); @@ -579,6 +733,10 @@ public class UploadPackTest { new StringWriter(), NullOutputStream.INSTANCE); PackParser pp = client.newObjectInserter().newPackParser(sb); pp.parse(NullProgressMonitor.INSTANCE); + + // Ensure that there is nothing left in the stream. + assertEquals(-1, recvStream.read()); + return pp.getReceivedPackStatistics(); } @@ -592,6 +750,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.ADVERTISED, null, + null, "command=fetch\n", PacketLineIn.DELIM, "want " + advertized.name() + "\n", @@ -604,6 +763,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.ADVERTISED, null, + null, "command=fetch\n", PacketLineIn.DELIM, "want " + unadvertized.name() + "\n", @@ -621,6 +781,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.REACHABLE_COMMIT, null, + null, "command=fetch\n", PacketLineIn.DELIM, "want " + reachable.name() + "\n", @@ -633,6 +794,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.REACHABLE_COMMIT, null, + null, "command=fetch\n", PacketLineIn.DELIM, "want " + unreachable.name() + "\n", @@ -649,6 +811,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.TIP, new RejectAllRefFilter(), + null, "command=fetch\n", PacketLineIn.DELIM, "want " + tip.name() + "\n", @@ -661,6 +824,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.TIP, new RejectAllRefFilter(), + null, "command=fetch\n", PacketLineIn.DELIM, "want " + parentOfTip.name() + "\n", @@ -678,6 +842,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.REACHABLE_COMMIT_TIP, new RejectAllRefFilter(), + null, "command=fetch\n", PacketLineIn.DELIM, "want " + parentOfTip.name() + "\n", @@ -690,6 +855,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.REACHABLE_COMMIT_TIP, new RejectAllRefFilter(), + null, "command=fetch\n", PacketLineIn.DELIM, "want " + unreachable.name() + "\n", @@ -704,6 +870,7 @@ public class UploadPackTest { uploadPackV2( RequestPolicy.ANY, null, + null, "command=fetch\n", PacketLineIn.DELIM, "want " + unreachable.name() + "\n", @@ -1078,6 +1245,216 @@ public class UploadPackTest { PacketLineIn.END); } + @Test + public void testV2FetchWantRefIfNotAllowed() throws Exception { + RevCommit one = remote.commit().message("1").create(); + remote.update("one", one); + + try { + uploadPackV2( + "command=fetch\n", + PacketLineIn.DELIM, + "want-ref refs/heads/one\n", + "done\n", + PacketLineIn.END); + } catch (PackProtocolException e) { + assertThat( + e.getMessage(), + containsString("unexpected want-ref refs/heads/one")); + return; + } + fail("expected PackProtocolException"); + } + + @Test + public void testV2FetchWantRef() throws Exception { + RevCommit one = remote.commit().message("1").create(); + RevCommit two = remote.commit().message("2").create(); + RevCommit three = remote.commit().message("3").create(); + remote.update("one", one); + remote.update("two", two); + remote.update("three", three); + + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); + + ByteArrayInputStream recvStream = uploadPackV2( + "command=fetch\n", + PacketLineIn.DELIM, + "want-ref refs/heads/one\n", + "want-ref refs/heads/two\n", + "done\n", + PacketLineIn.END); + PacketLineIn pckIn = new PacketLineIn(recvStream); + assertThat(pckIn.readString(), is("wanted-refs")); + assertThat( + Arrays.asList(pckIn.readString(), pckIn.readString()), + hasItems( + one.toObjectId().getName() + " refs/heads/one", + two.toObjectId().getName() + " refs/heads/two")); + assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertThat(pckIn.readString(), is("packfile")); + parsePack(recvStream); + + assertTrue(client.hasObject(one.toObjectId())); + assertTrue(client.hasObject(two.toObjectId())); + assertFalse(client.hasObject(three.toObjectId())); + } + + @Test + public void testV2FetchBadWantRef() throws Exception { + RevCommit one = remote.commit().message("1").create(); + remote.update("one", one); + + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); + + try { + uploadPackV2( + "command=fetch\n", + PacketLineIn.DELIM, + "want-ref refs/heads/one\n", + "want-ref refs/heads/nonExistentRef\n", + "done\n", + PacketLineIn.END); + } catch (PackProtocolException e) { + assertThat( + e.getMessage(), + containsString("Invalid ref name: refs/heads/nonExistentRef")); + return; + } + fail("expected PackProtocolException"); + } + + @Test + public void testV2FetchMixedWantRef() throws Exception { + RevCommit one = remote.commit().message("1").create(); + RevCommit two = remote.commit().message("2").create(); + RevCommit three = remote.commit().message("3").create(); + remote.update("one", one); + remote.update("two", two); + remote.update("three", three); + + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); + + ByteArrayInputStream recvStream = uploadPackV2( + "command=fetch\n", + PacketLineIn.DELIM, + "want-ref refs/heads/one\n", + "want " + two.toObjectId().getName() + "\n", + "done\n", + PacketLineIn.END); + PacketLineIn pckIn = new PacketLineIn(recvStream); + assertThat(pckIn.readString(), is("wanted-refs")); + assertThat( + pckIn.readString(), + is(one.toObjectId().getName() + " refs/heads/one")); + assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertThat(pckIn.readString(), is("packfile")); + parsePack(recvStream); + + assertTrue(client.hasObject(one.toObjectId())); + assertTrue(client.hasObject(two.toObjectId())); + assertFalse(client.hasObject(three.toObjectId())); + } + + @Test + public void testV2FetchWantRefWeAlreadyHave() throws Exception { + RevCommit one = remote.commit().message("1").create(); + remote.update("one", one); + + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); + + ByteArrayInputStream recvStream = uploadPackV2( + "command=fetch\n", + PacketLineIn.DELIM, + "want-ref refs/heads/one\n", + "have " + one.toObjectId().getName(), + "done\n", + PacketLineIn.END); + PacketLineIn pckIn = new PacketLineIn(recvStream); + + // The client still needs to know the hash of the object that + // refs/heads/one points to, even though it already has the + // object ... + assertThat(pckIn.readString(), is("wanted-refs")); + assertThat( + pckIn.readString(), + is(one.toObjectId().getName() + " refs/heads/one")); + assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + + // ... but the client does not need the object itself. + assertThat(pckIn.readString(), is("packfile")); + parsePack(recvStream); + assertFalse(client.hasObject(one.toObjectId())); + } + + @Test + public void testV2FetchWantRefAndDeepen() throws Exception { + RevCommit parent = remote.commit().message("parent").create(); + RevCommit child = remote.commit().message("x").parent(parent).create(); + remote.update("branch1", child); + + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); + + ByteArrayInputStream recvStream = uploadPackV2( + "command=fetch\n", + PacketLineIn.DELIM, + "want-ref refs/heads/branch1\n", + "deepen 1\n", + "done\n", + PacketLineIn.END); + PacketLineIn pckIn = new PacketLineIn(recvStream); + + // shallow-info appears first, then wanted-refs. + assertThat(pckIn.readString(), is("shallow-info")); + assertThat(pckIn.readString(), is("shallow " + child.toObjectId().getName())); + assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertThat(pckIn.readString(), is("wanted-refs")); + assertThat(pckIn.readString(), is(child.toObjectId().getName() + " refs/heads/branch1")); + assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertThat(pckIn.readString(), is("packfile")); + parsePack(recvStream); + assertTrue(client.hasObject(child.toObjectId())); + assertFalse(client.hasObject(parent.toObjectId())); + } + + @Test + public void testV2FetchMissingShallow() throws Exception { + RevCommit one = remote.commit().message("1").create(); + RevCommit two = remote.commit().message("2").parent(one).create(); + RevCommit three = remote.commit().message("3").parent(two).create(); + remote.update("three", three); + + server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", + true); + + ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n", + PacketLineIn.DELIM, + "want-ref refs/heads/three\n", + "deepen 3", + "shallow 0123012301230123012301230123012301230123", + "shallow " + two.getName() + '\n', + "done\n", + PacketLineIn.END); + PacketLineIn pckIn = new PacketLineIn(recvStream); + + assertThat(pckIn.readString(), is("shallow-info")); + assertThat(pckIn.readString(), + is("shallow " + one.toObjectId().getName())); + assertThat(pckIn.readString(), + is("unshallow " + two.toObjectId().getName())); + assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertThat(pckIn.readString(), is("wanted-refs")); + assertThat(pckIn.readString(), + is(three.toObjectId().getName() + " refs/heads/three")); + assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertThat(pckIn.readString(), is("packfile")); + parsePack(recvStream); + + assertTrue(client.hasObject(one.toObjectId())); + assertTrue(client.hasObject(two.toObjectId())); + assertTrue(client.hasObject(three.toObjectId())); + } + 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/transport/WalkEncryptionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java index 33e2529731..f2fb0224ef 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.cryptoCipherListPBE; import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.cryptoCipherListTrans; import static org.eclipse.jgit.transport.WalkEncryptionTest.Util.folderDelete; @@ -360,7 +360,7 @@ public class WalkEncryptionTest { * @throws Exception */ static String textRead(File file) throws Exception { - return new String(Files.readAllBytes(file.toPath()), CHARSET); + return new String(Files.readAllBytes(file.toPath()), UTF_8); } /** @@ -371,7 +371,7 @@ public class WalkEncryptionTest { * @throws Exception */ static void textWrite(File file, String text) throws Exception { - Files.write(file.toPath(), text.getBytes(CHARSET)); + Files.write(file.toPath(), text.getBytes(UTF_8)); } static void verifyFileContent(File fileOne, File fileTwo) @@ -420,7 +420,7 @@ public class WalkEncryptionTest { c.setConnectTimeout(500); c.setReadTimeout(500); try (BufferedReader reader = new BufferedReader( - new InputStreamReader(c.getInputStream()))) { + new InputStreamReader(c.getInputStream(), UTF_8))) { return reader.readLine(); } } catch (UnknownHostException | SocketTimeoutException e) { @@ -738,7 +738,7 @@ public class WalkEncryptionTest { AmazonS3 s3 = new AmazonS3(props); String file = JGIT_USER + "-" + UUID.randomUUID().toString(); String path = JGIT_REMOTE_DIR + "/" + file; - s3.put(bucket, path, file.getBytes(CHARSET)); + s3.put(bucket, path, file.getBytes(UTF_8)); s3.delete(bucket, path); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/CanonicalTreeParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/CanonicalTreeParserTest.java index 6195e640fb..41bd355a2f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/CanonicalTreeParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/CanonicalTreeParserTest.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.treewalk; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.FileMode.REGULAR_FILE; import static org.eclipse.jgit.lib.FileMode.SYMLINK; import static org.junit.Assert.assertEquals; @@ -110,7 +111,7 @@ public class CanonicalTreeParserTest { } private String path() { - return RawParseUtils.decode(Constants.CHARSET, ctp.path, + return RawParseUtils.decode(UTF_8, ctp.path, ctp.pathOffset, ctp.pathLen); } @@ -370,7 +371,7 @@ public class CanonicalTreeParserTest { final String name = b.toString(); ctp.reset(entry(m644, name, hash_a)); assertFalse(ctp.eof()); - assertEquals(name, RawParseUtils.decode(Constants.CHARSET, ctp.path, + assertEquals(name, RawParseUtils.decode(UTF_8, ctp.path, ctp.pathOffset, ctp.pathLen)); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java index 0e009b9540..33e32cd813 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.treewalk; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -331,7 +332,7 @@ public class FileTreeIteratorTest extends RepositoryTestCase { DirCacheEntry dce = db.readDirCache().getEntry("symlink"); dce.setFileMode(FileMode.SYMLINK); try (ObjectReader objectReader = db.newObjectReader()) { - DirCacheCheckout.checkoutEntry(db, dce, objectReader); + DirCacheCheckout.checkoutEntry(db, dce, objectReader, false, null); FileTreeIterator fti = new FileTreeIterator(trash, db.getFS(), db.getConfig().get(WorkingTreeOptions.KEY)); @@ -822,6 +823,6 @@ public class FileTreeIteratorTest extends RepositoryTestCase { } private static String nameOf(AbstractTreeIterator i) { - return RawParseUtils.decode(Constants.CHARSET, i.path, 0, i.pathLen); + return RawParseUtils.decode(UTF_8, i.path, 0, i.pathLen); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java index 71a2f327c8..15d03d38e7 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java @@ -231,8 +231,8 @@ public class PathFilterGroupTest { } } - String[] e = expect.toArray(new String[expect.size()]); - String[] a = actual.toArray(new String[actual.size()]); + String[] e = expect.toArray(new String[0]); + String[] a = actual.toArray(new String[0]); Arrays.sort(e); Arrays.sort(a); assertArrayEquals(e, a); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FilterCommandsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FilterCommandsTest.java index 0d31811257..8dfdd0fc7c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FilterCommandsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FilterCommandsTest.java @@ -85,6 +85,8 @@ public class FilterCommandsTest extends RepositoryTestCase { public int run() throws IOException { int b = in.read(); if (b == -1) { + in.close(); + out.close(); return b; } out.write(prefix); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RawParseUtilsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RawParseUtilsTest.java index 7bd9adb90c..3aae59e908 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RawParseUtilsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RawParseUtilsTest.java @@ -52,7 +52,24 @@ import java.nio.charset.UnsupportedCharsetException; import org.eclipse.jgit.lib.Constants; import org.junit.Test; +import static java.nio.charset.StandardCharsets.UTF_8; + public class RawParseUtilsTest { + String commit = "tree e3a1035abd2b319bb01e57d69b0ba6cab289297e\n" + + "parent 54e895b87c0768d2317a2b17062e3ad9f76a8105\n" + + "committer A U Thor <author@xample.com 1528968566 +0200\n" + + "gpgsig -----BEGIN PGP SIGNATURE-----\n" + + " \n" + + " wsBcBAABCAAQBQJbGB4pCRBK7hj4Ov3rIwAAdHIIAENrvz23867ZgqrmyPemBEZP\n" + + " U24B1Tlq/DWvce2buaxmbNQngKZ0pv2s8VMc11916WfTIC9EKvioatmpjduWvhqj\n" + + " znQTFyiMor30pyYsfrqFuQZvqBW01o8GEWqLg8zjf9Rf0R3LlOEw86aT8CdHRlm6\n" + + " wlb22xb8qoX4RB+LYfz7MhK5F+yLOPXZdJnAVbuyoMGRnDpwdzjL5Hj671+XJxN5\n" + + " SasRdhxkkfw/ZnHxaKEc4juMz8Nziz27elRwhOQqlTYoXNJnsV//wy5Losd7aKi1\n" + + " xXXyUpndEOmT0CIcKHrN/kbYoVL28OJaxoBuva3WYQaRrzEe3X02NMxZe9gkSqA=\n" + + " =TClh\n" + + " -----END PGP SIGNATURE-----\n" + + "some other header\n\n" + + "commit message"; @Test public void testParseEncoding_ISO8859_1_encoding() { @@ -79,4 +96,30 @@ public class RawParseUtilsTest { } } + @Test + public void testHeaderStart() { + byte[] headerName = "some".getBytes(UTF_8); + byte[] commitBytes = commit.getBytes(UTF_8); + assertEquals(625, RawParseUtils.headerStart(headerName, commitBytes, 0)); + assertEquals(625, RawParseUtils.headerStart(headerName, commitBytes, 4)); + + byte[] missingHeaderName = "missing".getBytes(UTF_8); + assertEquals(-1, RawParseUtils.headerStart(missingHeaderName, + commitBytes, 0)); + + byte[] fauxHeaderName = "other".getBytes(UTF_8); + assertEquals(-1, RawParseUtils.headerStart(fauxHeaderName, commitBytes, 625 + 4)); + } + + @Test + public void testHeaderEnd() { + byte[] commitBytes = commit.getBytes(UTF_8); + int[] expected = new int[] {45, 93, 148, 619, 637}; + int start = 0; + for (int i = 0; i < expected.length; i++) { + start = RawParseUtils.headerEnd(commitBytes, start); + assertEquals(expected[i], start); + start += 1; + } + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RawSubStringPatternTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RawSubStringPatternTest.java index a748b52215..e8566d2438 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RawSubStringPatternTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RawSubStringPatternTest.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.util; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -93,7 +93,7 @@ public class RawSubStringPatternTest extends RepositoryTestCase { } private static RawCharSequence raw(String text) { - byte[] bytes = text.getBytes(CHARSET); + byte[] bytes = text.getBytes(UTF_8); return new RawCharSequence(bytes, 0, bytes.length); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFInputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFInputStreamTest.java index 5058165802..37ca951f67 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFInputStreamTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFInputStreamTest.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.util.io; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import java.io.ByteArrayInputStream; @@ -132,6 +132,6 @@ public class AutoLFInputStreamTest { } private static byte[] asBytes(String in) { - return in.getBytes(CHARSET); + return in.getBytes(UTF_8); } } 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 3c612e1bdd..e6045a91bd 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 @@ -43,7 +43,7 @@ package org.eclipse.jgit.util.sha1; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -95,15 +95,15 @@ public class SHA1Test { .fromString("a9993e364706816aba3e25717850c26c9cd0d89d"); MessageDigest m = MessageDigest.getInstance("SHA-1"); - m.update(TEST1.getBytes(CHARSET)); + m.update(TEST1.getBytes(UTF_8)); ObjectId m1 = ObjectId.fromRaw(m.digest()); SHA1 s = SHA1.newInstance(); - s.update(TEST1.getBytes(CHARSET)); + s.update(TEST1.getBytes(UTF_8)); ObjectId s1 = ObjectId.fromRaw(s.digest()); s.reset(); - s.update(TEST1.getBytes(CHARSET)); + s.update(TEST1.getBytes(UTF_8)); ObjectId s2 = s.toObjectId(); assertEquals(m1, s1); @@ -117,15 +117,15 @@ public class SHA1Test { .fromString("84983e441c3bd26ebaae4aa1f95129e5e54670f1"); MessageDigest m = MessageDigest.getInstance("SHA-1"); - m.update(TEST2.getBytes(CHARSET)); + m.update(TEST2.getBytes(UTF_8)); ObjectId m1 = ObjectId.fromRaw(m.digest()); SHA1 s = SHA1.newInstance(); - s.update(TEST2.getBytes(CHARSET)); + s.update(TEST2.getBytes(UTF_8)); ObjectId s1 = ObjectId.fromRaw(s.digest()); s.reset(); - s.update(TEST2.getBytes(CHARSET)); + s.update(TEST2.getBytes(UTF_8)); ObjectId s2 = s.toObjectId(); assertEquals(m1, s1); diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF index 7667af4e96..c32f6a2538 100644 --- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF @@ -4,14 +4,14 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.ui Bundle-SymbolicName: org.eclipse.jgit.ui -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Vendor: %provider_name Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Export-Package: org.eclipse.jgit.awtui;version="5.0.4" -Import-Package: org.eclipse.jgit.errors;version="[5.0.4,5.1.0)", - org.eclipse.jgit.lib;version="[5.0.4,5.1.0)", - org.eclipse.jgit.nls;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revplot;version="[5.0.4,5.1.0)", - org.eclipse.jgit.revwalk;version="[5.0.4,5.1.0)", - org.eclipse.jgit.transport;version="[5.0.4,5.1.0)", - org.eclipse.jgit.util;version="[5.0.4,5.1.0)" +Export-Package: org.eclipse.jgit.awtui;version="5.1.3" +Import-Package: org.eclipse.jgit.errors;version="[5.1.3,5.2.0)", + org.eclipse.jgit.lib;version="[5.1.3,5.2.0)", + org.eclipse.jgit.nls;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revplot;version="[5.1.3,5.2.0)", + org.eclipse.jgit.revwalk;version="[5.1.3,5.2.0)", + org.eclipse.jgit.transport;version="[5.1.3,5.2.0)", + org.eclipse.jgit.util;version="[5.1.3,5.2.0)" diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml index 7d10c09833..5a4c8fc92d 100644 --- a/org.eclipse.jgit.ui/pom.xml +++ b/org.eclipse.jgit.ui/pom.xml @@ -52,7 +52,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ui</artifactId> diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index 089510ac51..f96336d596 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -3,8 +3,8 @@ <resource path="META-INF/MANIFEST.MF"> <filter id="924844039"> <message_arguments> - <message_argument value="5.0.4"/> - <message_argument value="5.0.0"/> + <message_argument value="5.1.3"/> + <message_argument value="5.1.0"/> </message_arguments> </filter> </resource> @@ -24,22 +24,4 @@ </message_arguments> </filter> </resource> - <resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS"> - <filter id="1141899266"> - <message_arguments> - <message_argument value="4.7"/> - <message_argument value="5.0"/> - <message_argument value="createNewFileAtomic(File)"/> - </message_arguments> - </filter> - </resource> - <resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS$LockToken"> - <filter id="1141899266"> - <message_arguments> - <message_argument value="4.7"/> - <message_argument value="5.0"/> - <message_argument value="LockToken"/> - </message_arguments> - </filter> - </resource> </component> diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index a8114d9527..39494aedda 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF @@ -3,12 +3,12 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit Bundle-SymbolicName: org.eclipse.jgit -Bundle-Version: 5.0.4.qualifier +Bundle-Version: 5.1.3.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.jgit.annotations;version="5.0.4", - org.eclipse.jgit.api;version="5.0.4"; +Export-Package: org.eclipse.jgit.annotations;version="5.1.3", + org.eclipse.jgit.api;version="5.1.3"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff, @@ -22,52 +22,52 @@ Export-Package: org.eclipse.jgit.annotations;version="5.0.4", org.eclipse.jgit.submodule, org.eclipse.jgit.transport, org.eclipse.jgit.merge", - org.eclipse.jgit.api.errors;version="5.0.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", - org.eclipse.jgit.attributes;version="5.0.4", - org.eclipse.jgit.blame;version="5.0.4"; + org.eclipse.jgit.api.errors;version="5.1.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", + org.eclipse.jgit.attributes;version="5.1.3", + org.eclipse.jgit.blame;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff", - org.eclipse.jgit.diff;version="5.0.4"; + org.eclipse.jgit.diff;version="5.1.3"; uses:="org.eclipse.jgit.patch, org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util", - org.eclipse.jgit.dircache;version="5.0.4"; + org.eclipse.jgit.dircache;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.util, org.eclipse.jgit.events, org.eclipse.jgit.attributes", - org.eclipse.jgit.errors;version="5.0.4"; + org.eclipse.jgit.errors;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.internal.storage.pack, org.eclipse.jgit.transport, org.eclipse.jgit.dircache", - org.eclipse.jgit.events;version="5.0.4";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.fnmatch;version="5.0.4", - org.eclipse.jgit.gitrepo;version="5.0.4"; + org.eclipse.jgit.events;version="5.1.3";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.fnmatch;version="5.1.3", + org.eclipse.jgit.gitrepo;version="5.1.3"; uses:="org.eclipse.jgit.api, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.xml.sax.helpers, org.xml.sax", - org.eclipse.jgit.gitrepo.internal;version="5.0.4";x-internal:=true, - org.eclipse.jgit.hooks;version="5.0.4";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.ignore;version="5.0.4", - org.eclipse.jgit.ignore.internal;version="5.0.4";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal;version="5.0.4";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.fsck;version="5.0.4";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.ketch;version="5.0.4";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.dfs;version="5.0.4"; + org.eclipse.jgit.gitrepo.internal;version="5.1.3";x-internal:=true, + org.eclipse.jgit.hooks;version="5.1.3";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.ignore;version="5.1.3", + org.eclipse.jgit.ignore.internal;version="5.1.3";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal;version="5.1.3";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", + org.eclipse.jgit.internal.fsck;version="5.1.3";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal.ketch;version="5.1.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.dfs;version="5.1.3"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.http.server, org.eclipse.jgit.http.test, org.eclipse.jgit.lfs.test", - org.eclipse.jgit.internal.storage.file;version="5.0.4"; + org.eclipse.jgit.internal.storage.file;version="5.1.3"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.junit, org.eclipse.jgit.junit.http, @@ -75,12 +75,12 @@ Export-Package: org.eclipse.jgit.annotations;version="5.0.4", org.eclipse.jgit.lfs, org.eclipse.jgit.pgm, org.eclipse.jgit.pgm.test", - org.eclipse.jgit.internal.storage.io;version="5.0.4";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.pack;version="5.0.4";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftable;version="5.0.4"; + org.eclipse.jgit.internal.storage.io;version="5.1.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.pack;version="5.1.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.reftable;version="5.1.3"; x-friends:="org.eclipse.jgit.http.test,org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftree;version="5.0.4";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.lib;version="5.0.4"; + org.eclipse.jgit.internal.storage.reftree;version="5.1.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.lib;version="5.1.3"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util, @@ -90,33 +90,33 @@ Export-Package: org.eclipse.jgit.annotations;version="5.0.4", org.eclipse.jgit.treewalk, org.eclipse.jgit.transport, org.eclipse.jgit.submodule", - org.eclipse.jgit.lib.internal;version="5.0.4";x-internal:=true, - org.eclipse.jgit.merge;version="5.0.4"; + org.eclipse.jgit.lib.internal;version="5.1.3";x-internal:=true, + org.eclipse.jgit.merge;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.diff, org.eclipse.jgit.dircache, org.eclipse.jgit.api", - org.eclipse.jgit.nls;version="5.0.4", - org.eclipse.jgit.notes;version="5.0.4"; + org.eclipse.jgit.nls;version="5.1.3", + org.eclipse.jgit.notes;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.merge", - org.eclipse.jgit.patch;version="5.0.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", - org.eclipse.jgit.revplot;version="5.0.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", - org.eclipse.jgit.revwalk;version="5.0.4"; + org.eclipse.jgit.patch;version="5.1.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", + org.eclipse.jgit.revplot;version="5.1.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", + org.eclipse.jgit.revwalk;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff, org.eclipse.jgit.revwalk.filter", - org.eclipse.jgit.revwalk.filter;version="5.0.4";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.file;version="5.0.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.pack;version="5.0.4";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.submodule;version="5.0.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", - org.eclipse.jgit.transport;version="5.0.4"; + org.eclipse.jgit.revwalk.filter;version="5.1.3";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.file;version="5.1.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.pack;version="5.1.3";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.submodule;version="5.1.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", + org.eclipse.jgit.transport;version="5.1.3"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.revwalk, org.eclipse.jgit.internal.storage.pack, @@ -128,24 +128,24 @@ Export-Package: org.eclipse.jgit.annotations;version="5.0.4", org.eclipse.jgit.transport.http, org.eclipse.jgit.errors, org.eclipse.jgit.storage.pack", - org.eclipse.jgit.transport.http;version="5.0.4";uses:="javax.net.ssl", - org.eclipse.jgit.transport.resolver;version="5.0.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", - org.eclipse.jgit.treewalk;version="5.0.4"; + org.eclipse.jgit.transport.http;version="5.1.3";uses:="javax.net.ssl", + org.eclipse.jgit.transport.resolver;version="5.1.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", + org.eclipse.jgit.treewalk;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.attributes, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util, org.eclipse.jgit.dircache", - org.eclipse.jgit.treewalk.filter;version="5.0.4";uses:="org.eclipse.jgit.treewalk", - org.eclipse.jgit.util;version="5.0.4"; + org.eclipse.jgit.treewalk.filter;version="5.1.3";uses:="org.eclipse.jgit.treewalk", + org.eclipse.jgit.util;version="5.1.3"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.transport.http, org.eclipse.jgit.storage.file, org.ietf.jgss", - org.eclipse.jgit.util.io;version="5.0.4", - org.eclipse.jgit.util.sha1;version="5.0.4", - org.eclipse.jgit.util.time;version="5.0.4" + org.eclipse.jgit.util.io;version="5.1.3", + org.eclipse.jgit.util.sha1;version="5.1.3", + org.eclipse.jgit.util.time;version="5.1.3" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", com.jcraft.jsch;version="[0.1.37,0.2.0)", diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF index b2d694a88c..eec78019e6 100644 --- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF @@ -3,5 +3,5 @@ Bundle-ManifestVersion: 2 Bundle-Name: org.eclipse.jgit - Sources Bundle-SymbolicName: org.eclipse.jgit.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 5.0.4.qualifier -Eclipse-SourceBundle: org.eclipse.jgit;version="5.0.4.qualifier";roots="." +Bundle-Version: 5.1.3.qualifier +Eclipse-SourceBundle: org.eclipse.jgit;version="5.1.3.qualifier";roots="." diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml index 2b56d0ae1f..7d8b326e8d 100644 --- a/org.eclipse.jgit/pom.xml +++ b/org.eclipse.jgit/pom.xml @@ -53,7 +53,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit</artifactId> @@ -84,10 +84,6 @@ <artifactId>JavaEWAH</artifactId> </dependency> - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> - </dependency> <dependency> <groupId>org.slf4j</groupId> diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index bbea8a3d24..3f1d21289f 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -582,6 +582,7 @@ remoteNameCantBeNull=Remote name can't be null. renameBranchFailedBecauseTag=Can not rename as Ref {0} is a tag renameBranchFailedUnknownReason=Rename failed with unknown reason renameBranchUnexpectedResult=Unexpected rename result {0} +renameCancelled=Rename detection was cancelled renameFileFailed=Could not rename file {0} to {1} renamesAlreadyFound=Renames have already been found. renamesBreakingModifies=Breaking apart modified file pairs @@ -765,8 +766,8 @@ updatingRefFailed=Updating the ref {0} to {1} failed. ReturnCode from RefUpdate. upstreamBranchName=branch ''{0}'' of {1} uriNotConfigured=Submodule URI not configured uriNotFound={0} not found +uriNotFoundWithMessage={0} not found: {1} URINotSupported=URI not supported: {0} -URLNotFound={0} not found userConfigFileInvalid=User config file {0} invalid {1} walkFailure=Walk failure. wantNotValid=want {0} not valid diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java index 0d9fe41afb..43085dc775 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java @@ -136,7 +136,7 @@ public class CleanCommand extends GitCommand<Set<String>> { } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } finally { - if (!files.isEmpty()) { + if (!dryRun && !files.isEmpty()) { repo.fireEvent(new WorkingTreeModifiedEvent(null, files)); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java index 98c16b8931..1783c4193e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -275,9 +275,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { throw new JGitInternalException(ioe.getMessage(), ioe); } case PROCESS_STEPS: - // fall through case SKIP: - // fall through case CONTINUE: String upstreamCommitId = rebaseState.readFile(ONTO); try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java index 9d9626f5a4..244a15686f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java @@ -77,6 +77,8 @@ import org.eclipse.jgit.treewalk.filter.TreeFilter; public class SubmoduleAddCommand extends TransportCommand<SubmoduleAddCommand, Repository> { + private String name; + private String path; private String uri; @@ -94,6 +96,18 @@ public class SubmoduleAddCommand extends } /** + * Set the submodule name + * + * @param name + * @return this command + * @since 5.1 + */ + public SubmoduleAddCommand setName(String name) { + this.name = name; + return this; + } + + /** * Set repository-relative path of submodule * * @param path @@ -161,9 +175,28 @@ public class SubmoduleAddCommand extends throw new IllegalArgumentException(JGitText.get().pathNotConfigured); if (uri == null || uri.length() == 0) throw new IllegalArgumentException(JGitText.get().uriNotConfigured); + if (name == null || name.length() == 0) { + // Use the path as the default. + name = path; + } + if (name.contains("/../") || name.contains("\\..\\") //$NON-NLS-1$ //$NON-NLS-2$ + || name.startsWith("../") || name.startsWith("..\\") //$NON-NLS-1$ //$NON-NLS-2$ + || name.endsWith("/..") || name.endsWith("\\..")) { //$NON-NLS-1$ //$NON-NLS-2$ + // Submodule names are used to store the submodule repositories + // under $GIT_DIR/modules. Having ".." in submodule names makes a + // vulnerability (CVE-2018-11235 + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=535027#c0) + // Reject the names with them. The callers need to make sure the + // names free from these. We don't automatically replace these + // characters or canonicalize by regarding the name as a file path. + // Since Path class is platform dependent, we manually check '/' and + // '\\' patterns here. + throw new IllegalArgumentException(MessageFormat + .format(JGitText.get().invalidNameContainsDotDot, name)); + } try { - SubmoduleValidator.assertValidSubmoduleName(path); + SubmoduleValidator.assertValidSubmoduleName(name); SubmoduleValidator.assertValidSubmodulePath(path); SubmoduleValidator.assertValidSubmoduleUri(uri); } catch (SubmoduleValidator.SubmoduleValidationException e) { @@ -202,7 +235,7 @@ public class SubmoduleAddCommand extends // Save submodule URL to parent repository's config StoredConfig config = repo.getConfig(); - config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, + config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, name, ConfigConstants.CONFIG_KEY_URL, resolvedUri); try { config.save(); @@ -216,9 +249,9 @@ public class SubmoduleAddCommand extends try { modulesConfig.load(); modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, - path, ConfigConstants.CONFIG_KEY_PATH, path); + name, ConfigConstants.CONFIG_KEY_PATH, path); modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, - path, ConfigConstants.CONFIG_KEY_URL, uri); + name, ConfigConstants.CONFIG_KEY_URL, uri); modulesConfig.save(); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java index 569a8e3596..5a0528b0f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java @@ -227,11 +227,11 @@ public class SubmoduleDeinitCommand return SubmoduleDeinitStatus.DIRTY; } - Repository submoduleRepo = w.getRepository(); - - Status status = Git.wrap(submoduleRepo).status().call(); - return status.isClean() ? SubmoduleDeinitStatus.SUCCESS - : SubmoduleDeinitStatus.DIRTY; + try (Repository submoduleRepo = w.getRepository()) { + Status status = Git.wrap(submoduleRepo).status().call(); + return status.isClean() ? SubmoduleDeinitStatus.SUCCESS + : SubmoduleDeinitStatus.DIRTY; + } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java index 62bf9f2737..bcd72311dd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java @@ -42,6 +42,8 @@ */ package org.eclipse.jgit.attributes; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -50,8 +52,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.eclipse.jgit.lib.Constants; - /** * Represents a bundle of attributes inherited from a base directory. * @@ -115,7 +115,7 @@ public class AttributesNode { } private static BufferedReader asReader(InputStream in) { - return new BufferedReader(new InputStreamReader(in, Constants.CHARSET)); + return new BufferedReader(new InputStreamReader(in, UTF_8)); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java index 1ad7a3055a..9cec645679 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java @@ -539,7 +539,7 @@ public class BlameGenerator implements AutoCloseable { n.beginResult(revPool); outCandidate = n; outRegion = n.regionList; - return true; + return outRegion != null; } private boolean reverseResult(Candidate parent, Candidate source) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java index 21dca6b78c..ca37a10c5a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java @@ -82,7 +82,7 @@ public class DiffConfig { renameDetectionType = parseRenameDetectionType(rc.getString( ConfigConstants.CONFIG_DIFF_SECTION, null, ConfigConstants.CONFIG_KEY_RENAMES)); renameLimit = rc.getInt(ConfigConstants.CONFIG_DIFF_SECTION, - ConfigConstants.CONFIG_KEY_RENAMELIMIT, 200); + ConfigConstants.CONFIG_KEY_RENAMELIMIT, 400); } /** 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 7aaa50030f..e7ad0bc40d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java @@ -67,6 +67,7 @@ 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; @@ -577,7 +578,14 @@ public class DiffFormatter implements AutoCloseable { throws IOException { renameDetector.reset(); renameDetector.addAll(files); - return renameDetector.compute(reader, progressMonitor); + try { + return renameDetector.compute(reader, progressMonitor); + } catch (CancelledException e) { + // TODO: consider propagating once bug 536323 is tackled + // (making DiffEntry.scan() and DiffFormatter.scan() and + // format() cancellable). + return Collections.emptyList(); + } } private boolean isAdd(List<DiffEntry> files) { 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 7bb217d04d..772fbb5ffe 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java @@ -57,6 +57,7 @@ import java.util.List; 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; @@ -332,8 +333,13 @@ public class RenameDetector { * representing all files that have been changed. * @throws java.io.IOException * file contents cannot be read from the repository. + * @throws CancelledException + * if rename detection was cancelled */ - public List<DiffEntry> compute(ProgressMonitor pm) throws IOException { + // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major + // version + public List<DiffEntry> compute(ProgressMonitor pm) + throws IOException, CancelledException { if (!done) { try { return compute(objectReader, pm); @@ -355,9 +361,13 @@ public class RenameDetector { * representing all files that have been changed. * @throws java.io.IOException * file contents cannot be read from the repository. + * @throws CancelledException + * if rename detection was cancelled */ + // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major + // version public List<DiffEntry> compute(ObjectReader reader, ProgressMonitor pm) - throws IOException { + throws IOException, CancelledException { final ContentSource cs = ContentSource.create(reader); return compute(new ContentSource.Pair(cs, cs), pm); } @@ -373,9 +383,13 @@ public class RenameDetector { * representing all files that have been changed. * @throws java.io.IOException * file contents cannot be read from the repository. + * @throws CancelledException + * if rename detection was cancelled */ + // TODO(ms): use org.eclipse.jgit.api.errors.CanceledException in next major + // version public List<DiffEntry> compute(ContentSource.Pair reader, ProgressMonitor pm) - throws IOException { + throws IOException, CancelledException { if (!done) { done = true; @@ -415,8 +429,15 @@ public class RenameDetector { done = false; } + private void advanceOrCancel(ProgressMonitor pm) throws CancelledException { + if (pm.isCancelled()) { + throw new CancelledException(JGitText.get().renameCancelled); + } + pm.update(1); + } + private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm) - throws IOException { + throws IOException, CancelledException { ArrayList<DiffEntry> newEntries = new ArrayList<>(entries.size()); pm.beginTask(JGitText.get().renamesBreakingModifies, entries.size()); @@ -437,13 +458,13 @@ public class RenameDetector { } else { newEntries.add(e); } - pm.update(1); + advanceOrCancel(pm); } entries = newEntries; } - private void rejoinModifies(ProgressMonitor pm) { + private void rejoinModifies(ProgressMonitor pm) throws CancelledException { HashMap<String, DiffEntry> nameMap = new HashMap<>(); ArrayList<DiffEntry> newAdded = new ArrayList<>(added.size()); @@ -452,7 +473,7 @@ public class RenameDetector { for (DiffEntry src : deleted) { nameMap.put(src.oldPath, src); - pm.update(1); + advanceOrCancel(pm); } for (DiffEntry dst : added) { @@ -468,7 +489,7 @@ public class RenameDetector { } else { newAdded.add(dst); } - pm.update(1); + advanceOrCancel(pm); } added = newAdded; @@ -498,7 +519,7 @@ public class RenameDetector { private void findContentRenames(ContentSource.Pair reader, ProgressMonitor pm) - throws IOException { + throws IOException, CancelledException { int cnt = Math.max(added.size(), deleted.size()); if (getRenameLimit() == 0 || cnt <= getRenameLimit()) { SimilarityRenameDetector d; @@ -516,7 +537,8 @@ public class RenameDetector { } @SuppressWarnings("unchecked") - private void findExactRenames(ProgressMonitor pm) { + private void findExactRenames(ProgressMonitor pm) + throws CancelledException { pm.beginTask(JGitText.get().renamesFindingExact, // added.size() + added.size() + deleted.size() + added.size() * deleted.size()); @@ -562,7 +584,7 @@ public class RenameDetector { } else { left.add(a); } - pm.update(1); + advanceOrCancel(pm); } for (List<DiffEntry> adds : nonUniqueAdds) { @@ -604,6 +626,10 @@ public class RenameDetector { int score = SimilarityRenameDetector.nameScore(addedName, deletedName); matrix[mNext] = SimilarityRenameDetector.encode(score, delIdx, addIdx); mNext++; + if (pm.isCancelled()) { + throw new CancelledException( + JGitText.get().renameCancelled); + } } } @@ -617,7 +643,7 @@ public class RenameDetector { DiffEntry a = adds.get(addIdx); if (a == null) { - pm.update(1); + advanceOrCancel(pm); continue; // was already matched earlier } @@ -635,11 +661,12 @@ public class RenameDetector { entries.add(DiffEntry.pair(type, d, a, 100)); adds.set(addIdx, null); // Claim the destination was matched. - pm.update(1); + advanceOrCancel(pm); } } else { left.addAll(adds); } + advanceOrCancel(pm); } added = left; @@ -692,7 +719,8 @@ public class RenameDetector { @SuppressWarnings("unchecked") private HashMap<AbbreviatedObjectId, Object> populateMap( - List<DiffEntry> diffEntries, ProgressMonitor pm) { + List<DiffEntry> diffEntries, ProgressMonitor pm) + throws CancelledException { HashMap<AbbreviatedObjectId, Object> map = new HashMap<>(); for (DiffEntry de : diffEntries) { Object old = map.put(id(de), de); @@ -706,7 +734,7 @@ public class RenameDetector { ((List<DiffEntry>) old).add(de); map.put(id(de), old); } - pm.update(1); + advanceOrCancel(pm); } return map; } 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 653658be3c..d8a05c34ea 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java @@ -54,6 +54,7 @@ import java.util.List; 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; @@ -128,7 +129,7 @@ class SimilarityRenameDetector { renameScore = score; } - void compute(ProgressMonitor pm) throws IOException { + void compute(ProgressMonitor pm) throws IOException, CancelledException { if (pm == null) pm = NullProgressMonitor.INSTANCE; @@ -142,6 +143,11 @@ class SimilarityRenameDetector { // we have looked at everything that is above our minimum score. // 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); + } long ent = matrix[mNext]; int sIdx = srcFile(ent); int dIdx = dstFile(ent); @@ -209,7 +215,8 @@ class SimilarityRenameDetector { return r; } - private int buildMatrix(ProgressMonitor pm) throws IOException { + private int buildMatrix(ProgressMonitor pm) + throws IOException, CancelledException { // Allocate for the worst-case scenario where every pair has a // score that we need to consider. We might not need that many. // @@ -234,6 +241,14 @@ class SimilarityRenameDetector { SimilarityIndex s = null; 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( + JGitText.get().renameCancelled); + } + DiffEntry dstEnt = dsts.get(dstIdx); if (!isFile(dstEnt.newMode)) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java index 0b03eb1521..ca1e3ab275 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -513,7 +513,7 @@ public class DirCacheCheckout { if (!conflicts.isEmpty()) { if (failOnConflict) - throw new CheckoutConflictException(conflicts.toArray(new String[conflicts.size()])); + throw new CheckoutConflictException(conflicts.toArray(new String[0])); else cleanUpConflicts(); } @@ -1366,7 +1366,11 @@ public class DirCacheCheckout { * object reader to use for checkout * @throws java.io.IOException * @since 3.6 + * @deprecated since 5.1, use + * {@link #checkoutEntry(Repository, DirCacheEntry, ObjectReader, boolean, CheckoutMetadata)} + * instead */ + @Deprecated public static void checkoutEntry(Repository repo, DirCacheEntry entry, ObjectReader or) throws IOException { checkoutEntry(repo, entry, or, false, null); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java index fee9f51000..6b1d4f4d8a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java @@ -46,6 +46,8 @@ package org.eclipse.jgit.dircache; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; @@ -772,7 +774,7 @@ public class DirCacheEntry { } static String toString(byte[] path) { - return Constants.CHARSET.decode(ByteBuffer.wrap(path)).toString(); + return UTF_8.decode(ByteBuffer.wrap(path)).toString(); } static int getMaximumInfoLength(boolean extended) { 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 b605f3ca8e..11a3474a35 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.dircache; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.FileMode.TREE; import static org.eclipse.jgit.lib.TreeFormatter.entrySize; @@ -276,7 +277,7 @@ public class DirCacheTree { */ public String getNameString() { final ByteBuffer bb = ByteBuffer.wrap(encodedName); - return Constants.CHARSET.decode(bb).toString(); + return UTF_8.decode(bb).toString(); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java index 929ffac114..26e783ddd7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java @@ -252,6 +252,9 @@ public class ManifestParser extends DefaultHandler { RepoText.get().errorIncludeFile, path), e); } } + } else if ("remove-project".equals(qName)) { //$NON-NLS-1$ + String name = attributes.getValue("name"); //$NON-NLS-1$ + projects.removeIf((p) -> p.getName().equals(name)); } } 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 80fd3cf1a4..45a239da0e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -55,8 +55,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.StringJoiner; +import java.util.TreeMap; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.Git; @@ -115,16 +115,15 @@ public class RepoCommand extends GitCommand<RevCommit> { private String groupsParam; private String branch; private String targetBranch = Constants.HEAD; - private boolean recordRemoteBranch = false; - private boolean recordSubmoduleLabels = false; - private boolean recordShallowSubmodules = false; + private boolean recordRemoteBranch = true; + private boolean recordSubmoduleLabels = true; + private boolean recordShallowSubmodules = true; private PersonIdent author; private RemoteReader callback; private InputStream inputStream; private IncludedFileReader includedReader; private boolean ignoreRemoteFailures = false; - private List<RepoProject> bareProjects; private ProgressMonitor monitor; /** @@ -519,37 +518,33 @@ public class RepoCommand extends GitCommand<RevCommit> { } if (repo.isBare()) { - bareProjects = new ArrayList<>(); if (author == null) author = new PersonIdent(repo); if (callback == null) callback = new DefaultRemoteReader(); - for (RepoProject proj : filteredProjects) { - addSubmoduleBare(proj.getUrl(), proj.getPath(), - proj.getRevision(), proj.getCopyFiles(), - proj.getLinkFiles(), proj.getGroups(), - proj.getRecommendShallow()); - } + List<RepoProject> renamedProjects = renameProjects(filteredProjects); + DirCache index = DirCache.newInCore(); DirCacheBuilder builder = index.builder(); ObjectInserter inserter = repo.newObjectInserter(); try (RevWalk rw = new RevWalk(repo)) { Config cfg = new Config(); StringBuilder attributes = new StringBuilder(); - for (RepoProject proj : bareProjects) { + for (RepoProject proj : renamedProjects) { + String name = proj.getName(); String path = proj.getPath(); - String nameUri = proj.getName(); + String url = proj.getUrl(); ObjectId objectId; if (ObjectId.isId(proj.getRevision())) { objectId = ObjectId.fromString(proj.getRevision()); } else { - objectId = callback.sha1(nameUri, proj.getRevision()); + objectId = callback.sha1(url, proj.getRevision()); if (objectId == null && !ignoreRemoteFailures) { - throw new RemoteUnavailableException(nameUri); + throw new RemoteUnavailableException(url); } if (recordRemoteBranch) { // can be branch or tag - cfg.setString("submodule", path, "branch", //$NON-NLS-1$ //$NON-NLS-2$ + cfg.setString("submodule", name, "branch", //$NON-NLS-1$ //$NON-NLS-2$ proj.getRevision()); } @@ -559,7 +554,7 @@ public class RepoCommand extends GitCommand<RevCommit> { // depth in the 'clone-depth' field, while // git core only uses a binary 'shallow = true/false' // hint, we'll map any depth to 'shallow = true' - cfg.setBoolean("submodule", path, "shallow", //$NON-NLS-1$ //$NON-NLS-2$ + cfg.setBoolean("submodule", name, "shallow", //$NON-NLS-1$ //$NON-NLS-2$ true); } } @@ -575,12 +570,13 @@ public class RepoCommand extends GitCommand<RevCommit> { attributes.append(rec.toString()); } - URI submodUrl = URI.create(nameUri); + URI submodUrl = URI.create(url); if (targetUri != null) { submodUrl = relativize(targetUri, submodUrl); } - cfg.setString("submodule", path, "path", path); //$NON-NLS-1$ //$NON-NLS-2$ - cfg.setString("submodule", path, "url", submodUrl.toString()); //$NON-NLS-1$ //$NON-NLS-2$ + cfg.setString("submodule", name, "path", path); //$NON-NLS-1$ //$NON-NLS-2$ + cfg.setString("submodule", name, "url", //$NON-NLS-1$ //$NON-NLS-2$ + submodUrl.toString()); // create gitlink if (objectId != null) { @@ -591,7 +587,7 @@ public class RepoCommand extends GitCommand<RevCommit> { for (CopyFile copyfile : proj.getCopyFiles()) { byte[] src = callback.readFile( - nameUri, proj.getRevision(), copyfile.src); + url, proj.getRevision(), copyfile.src); objectId = inserter.insert(Constants.OBJ_BLOB, src); dcEntry = new DirCacheEntry(copyfile.dest); dcEntry.setObjectId(objectId); @@ -691,7 +687,7 @@ public class RepoCommand extends GitCommand<RevCommit> { } else { try (Git git = new Git(repo)) { for (RepoProject proj : filteredProjects) { - addSubmodule(proj.getUrl(), proj.getPath(), + addSubmodule(proj.getName(), proj.getUrl(), proj.getPath(), proj.getRevision(), proj.getCopyFiles(), proj.getLinkFiles(), git); } @@ -703,9 +699,9 @@ public class RepoCommand extends GitCommand<RevCommit> { } } - private void addSubmodule(String url, String path, String revision, - List<CopyFile> copyfiles, List<LinkFile> linkfiles, Git git) - throws GitAPIException, IOException { + private void addSubmodule(String name, String url, String path, + String revision, List<CopyFile> copyfiles, List<LinkFile> linkfiles, + Git git) throws GitAPIException, IOException { assert (!repo.isBare()); assert (git != null); if (!linkfiles.isEmpty()) { @@ -713,7 +709,8 @@ public class RepoCommand extends GitCommand<RevCommit> { JGitText.get().nonBareLinkFilesNotSupported); } - SubmoduleAddCommand add = git.submoduleAdd().setPath(path).setURI(url); + SubmoduleAddCommand add = git.submoduleAdd().setName(name).setPath(path) + .setURI(url); if (monitor != null) add.setProgressMonitor(monitor); @@ -731,16 +728,42 @@ public class RepoCommand extends GitCommand<RevCommit> { } } - private void addSubmoduleBare(String url, String path, String revision, - List<CopyFile> copyfiles, List<LinkFile> linkfiles, - Set<String> groups, String recommendShallow) { - assert (repo.isBare()); - assert (bareProjects != null); - RepoProject proj = new RepoProject(url, path, revision, null, groups, - recommendShallow); - proj.addCopyFiles(copyfiles); - proj.addLinkFiles(linkfiles); - bareProjects.add(proj); + /** + * Rename the projects if there's a conflict when converted to submodules. + * + * @param projects + * parsed projects + * @return projects that are renamed if necessary + */ + private List<RepoProject> renameProjects(List<RepoProject> projects) { + Map<String, List<RepoProject>> m = new TreeMap<>(); + for (RepoProject proj : projects) { + List<RepoProject> l = m.get(proj.getName()); + if (l == null) { + l = new ArrayList<>(); + m.put(proj.getName(), l); + } + l.add(proj); + } + + List<RepoProject> ret = new ArrayList<>(); + for (List<RepoProject> ps : m.values()) { + boolean nameConflict = ps.size() != 1; + for (RepoProject proj : ps) { + String name = proj.getName(); + if (nameConflict) { + name += SLASH + proj.getPath(); + } + RepoProject p = new RepoProject(name, + proj.getPath(), proj.getRevision(), null, + proj.getGroups(), proj.getRecommendShallow()); + p.setUrl(proj.getUrl()); + p.addCopyFiles(proj.getCopyFiles()); + p.addLinkFiles(proj.getLinkFiles()); + ret.add(p); + } + } + return ret; } /* diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java index 8a61d1b0b1..ad43e2ca83 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java @@ -42,7 +42,7 @@ */ package org.eclipse.jgit.hooks; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -158,7 +158,7 @@ abstract class GitHook<T> implements Callable<T> { PrintStream hookErrRedirect = null; try { hookErrRedirect = new PrintStream(errorByteArray, false, - CHARSET.name()); + UTF_8.name()); } catch (UnsupportedEncodingException e) { // UTF-8 is guaranteed to be available } @@ -167,7 +167,7 @@ abstract class GitHook<T> implements Callable<T> { hookErrRedirect, getStdinArgs()); if (result.isExecutedWithError()) { throw new AbortedByHookException( - new String(errorByteArray.toByteArray(), CHARSET), + new String(errorByteArray.toByteArray(), UTF_8), getHookName(), result.getExitCode()); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java index d570fde36f..864f8bfc02 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java @@ -42,6 +42,8 @@ */ package org.eclipse.jgit.ignore; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -50,8 +52,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.eclipse.jgit.lib.Constants; - /** * Represents a bundle of ignore rules inherited from a base directory. * @@ -121,7 +121,7 @@ public class IgnoreNode { } private static BufferedReader asReader(InputStream in) { - return new BufferedReader(new InputStreamReader(in, Constants.CHARSET)); + return new BufferedReader(new InputStreamReader(in, UTF_8)); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index 18f4c85d88..c11ae5a526 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -643,6 +643,7 @@ public class JGitText extends TranslationBundle { /***/ public String renameBranchFailedBecauseTag; /***/ public String renameBranchFailedUnknownReason; /***/ public String renameBranchUnexpectedResult; + /***/ public String renameCancelled; /***/ public String renameFileFailed; /***/ public String renamesAlreadyFound; /***/ public String renamesBreakingModifies; @@ -826,8 +827,8 @@ public class JGitText extends TranslationBundle { /***/ public String upstreamBranchName; /***/ public String uriNotConfigured; /***/ public String uriNotFound; + /***/ public String uriNotFoundWithMessage; /***/ public String URINotSupported; - /***/ public String URLNotFound; /***/ public String userConfigFileInvalid; /***/ public String walkFailure; /***/ public String wantNotValid; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java index bc5ba3926b..fa32b267df 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java @@ -274,8 +274,8 @@ public abstract class KetchLeader { lock.lock(); try { - voters = v.toArray(new KetchReplica[v.size()]); - followers = f.toArray(new KetchReplica[f.size()]); + voters = v.toArray(new KetchReplica[0]); + followers = f.toArray(new KetchReplica[0]); self = me; } finally { lock.unlock(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java index 7ddde6337f..6f1f5c5c2c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java @@ -209,7 +209,7 @@ public class LocalReplica extends KetchReplica { checkFailed(failed, accepted); checkFailed(failed, committed); if (!failed.isEmpty()) { - String[] arr = failed.toArray(new String[failed.size()]); + String[] arr = failed.toArray(new String[0]); req.setRefs(refdb.exactRef(arr)); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsConfig.java index 3e2963af97..2f796a9d40 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsConfig.java @@ -48,7 +48,13 @@ import java.io.IOException; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.lib.StoredConfig; -final class DfsConfig extends StoredConfig { +/** + * Config implementation used by DFS repositories. + * <p> + * The current implementation acts as if there is no persistent storage: loading + * simply clears the config, and saving does nothing. + */ +public final class DfsConfig extends StoredConfig { /** {@inheritDoc} */ @Override public void load() throws IOException, ConfigInvalidException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsFsck.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsFsck.java index 985393c5e2..3f96d0919b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsFsck.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsFsck.java @@ -146,7 +146,7 @@ public class DfsFsck { throws IOException { pm.beginTask(JGitText.get().countingObjects, ProgressMonitor.UNKNOWN); try (ObjectWalk ow = new ObjectWalk(repo)) { - for (Ref r : repo.getAllRefs().values()) { + for (Ref r : repo.getRefDatabase().getRefs()) { ObjectId objectId = r.getObjectId(); if (objectId == null) { // skip unborn branch diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java index ca54ee22ea..09d59376a0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java @@ -43,13 +43,17 @@ package org.eclipse.jgit.internal.storage.dfs; +import static java.util.stream.Collectors.joining; + import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -86,10 +90,16 @@ public abstract class DfsObjDatabase extends ObjectDatabase { } }; - /** Sources for a pack file. */ + /** + * Sources for a pack file. + * <p> + * <strong>Note:</strong> When sorting packs by source, do not use the default + * comparator based on {@link Enum#compareTo}. Prefer {@link + * #DEFAULT_COMPARATOR} or your own {@link ComparatorBuilder}. + */ public static enum PackSource { /** The pack is created by ObjectInserter due to local activity. */ - INSERT(0), + INSERT, /** * The pack is created by PackParser due to a network event. @@ -100,7 +110,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * storage layout preferred by this version. Received packs are likely * to be either compacted or garbage collected in the future. */ - RECEIVE(0), + RECEIVE, /** * The pack was created by compacting multiple packs together. @@ -111,7 +121,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * * @see DfsPackCompactor */ - COMPACT(1), + COMPACT, /** * Pack was created by Git garbage collection by this implementation. @@ -122,17 +132,17 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * * @see DfsGarbageCollector */ - GC(2), + GC, /** Created from non-heads by {@link DfsGarbageCollector}. */ - GC_REST(3), + GC_REST, /** * RefTreeGraph pack was created by Git garbage collection. * * @see DfsGarbageCollector */ - GC_TXN(4), + GC_TXN, /** * Pack was created by Git garbage collection. @@ -141,12 +151,86 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * last GC pass. It is retained in a new pack until it is safe to prune * these objects from the repository. */ - UNREACHABLE_GARBAGE(5); + UNREACHABLE_GARBAGE; - final int category; + /** + * Default comparator for sources. + * <p> + * Sorts generally newer, smaller types such as {@code INSERT} and {@code + * RECEIVE} earlier; older, larger types such as {@code GC} later; and + * {@code UNREACHABLE_GARBAGE} at the end. + */ + public static final Comparator<PackSource> DEFAULT_COMPARATOR = + new ComparatorBuilder() + .add(INSERT, RECEIVE) + .add(COMPACT) + .add(GC) + .add(GC_REST) + .add(GC_TXN) + .add(UNREACHABLE_GARBAGE) + .build(); + + /** + * Builder for describing {@link PackSource} ordering where some values are + * explicitly considered equal to others. + */ + public static class ComparatorBuilder { + private final Map<PackSource, Integer> ranks = new HashMap<>(); + private int counter; + + /** + * Add a collection of sources that should sort as equal. + * <p> + * Sources in the input will sort after sources listed in previous calls + * to this method. + * + * @param sources + * sources in this equivalence class. + * @return this. + */ + public ComparatorBuilder add(PackSource... sources) { + for (PackSource s : sources) { + ranks.put(s, Integer.valueOf(counter)); + } + counter++; + return this; + } - PackSource(int category) { - this.category = category; + /** + * Build the comparator. + * + * @return new comparator instance. + * @throws IllegalArgumentException + * not all {@link PackSource} instances were explicitly assigned + * an equivalence class. + */ + public Comparator<PackSource> build() { + return new PackSourceComparator(ranks); + } + } + + private static class PackSourceComparator implements Comparator<PackSource> { + private final Map<PackSource, Integer> ranks; + + private PackSourceComparator(Map<PackSource, Integer> ranks) { + if (!ranks.keySet().equals( + new HashSet<>(Arrays.asList(PackSource.values())))) { + throw new IllegalArgumentException(); + } + this.ranks = new HashMap<>(ranks); + } + + @Override + public int compare(PackSource a, PackSource b) { + return ranks.get(a).compareTo(ranks.get(b)); + } + + @Override + public String toString() { + return Arrays.stream(PackSource.values()) + .map(s -> s + "=" + ranks.get(s)) //$NON-NLS-1$ + .collect(joining(", ", getClass().getSimpleName() + "{", "}")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } } } @@ -156,6 +240,8 @@ public abstract class DfsObjDatabase extends ObjectDatabase { private DfsReaderOptions readerOptions; + private Comparator<DfsPackDescription> packComparator; + /** * Initialize an object database for our repository. * @@ -169,6 +255,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { this.repository = repository; this.packList = new AtomicReference<>(NO_PACKS); this.readerOptions = options; + this.packComparator = DfsPackDescription.objectLookupComparator(); } /** @@ -180,6 +267,21 @@ public abstract class DfsObjDatabase extends ObjectDatabase { return readerOptions; } + /** + * Set the comparator used when searching for objects across packs. + * <p> + * An optimal comparator will find more objects without having to load large + * idx files from storage only to find that they don't contain the object. + * See {@link DfsPackDescription#objectLookupComparator()} for the default + * heuristics. + * + * @param packComparator + * comparator. + */ + public void setPackComparator(Comparator<DfsPackDescription> packComparator) { + this.packComparator = packComparator; + } + /** {@inheritDoc} */ @Override public DfsReader newReader() { @@ -523,7 +625,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { Map<DfsPackDescription, DfsReftable> reftables = reftableMap(old); List<DfsPackDescription> scanned = listPacks(); - Collections.sort(scanned); + Collections.sort(scanned, packComparator); List<DfsPackFile> newPacks = new ArrayList<>(scanned.size()); List<DfsReftable> newReftables = new ArrayList<>(scanned.size()); @@ -584,30 +686,9 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * @return comparator to sort {@link DfsReftable} by priority. */ protected Comparator<DfsReftable> reftableComparator() { - return (fa, fb) -> { - DfsPackDescription a = fa.getPackDescription(); - DfsPackDescription b = fb.getPackDescription(); - - // GC, COMPACT reftables first by higher category. - int c = category(b) - category(a); - if (c != 0) { - return c; - } - - // Lower maxUpdateIndex first. - c = Long.signum(a.getMaxUpdateIndex() - b.getMaxUpdateIndex()); - if (c != 0) { - return c; - } - - // Older reftable first. - return Long.signum(a.getLastModified() - b.getLastModified()); - }; - } - - static int category(DfsPackDescription d) { - PackSource s = d.getPackSource(); - return s != null ? s.category : 0; + return Comparator.comparing( + DfsReftable::getPackDescription, + DfsPackDescription.reftableComparator()); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java index b43b9b1780..127ee6bf11 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java @@ -404,12 +404,11 @@ public class DfsPackCompactor { // Sort packs by description ordering, this places newer packs before // older packs, allowing the PackWriter to be handed newer objects // first and older objects last. - Collections.sort(srcPacks, new Comparator<DfsPackFile>() { - @Override - public int compare(DfsPackFile a, DfsPackFile b) { - return a.getPackDescription().compareTo(b.getPackDescription()); - } - }); + Collections.sort( + srcPacks, + Comparator.comparing( + DfsPackFile::getPackDescription, + DfsPackDescription.objectLookupComparator())); rw = new RevWalk(ctx); added = rw.newFlag("ADDED"); //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java index 45eb7b0e1a..5a1ac02e25 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java @@ -47,7 +47,9 @@ import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE; import java.util.Arrays; +import java.util.Comparator; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.reftable.ReftableWriter; @@ -61,7 +63,107 @@ import org.eclipse.jgit.storage.pack.PackStatistics; * Instances of this class are cached with the DfsPackFile, and should not be * modified once initialized and presented to the JGit DFS library. */ -public class DfsPackDescription implements Comparable<DfsPackDescription> { +public class DfsPackDescription { + /** + * Comparator for packs when looking up objects in indexes. + * <p> + * This comparator tries to position packs in the order readers should examine + * them when looking for objects by SHA-1. The default tries to sort packs + * with more recent modification dates before older packs, and packs with + * fewer objects before packs with more objects. + * <p> + * Uses {@link PackSource#DEFAULT_COMPARATOR} for the portion of comparison + * where packs are sorted by source. + * + * @return comparator. + */ + public static Comparator<DfsPackDescription> objectLookupComparator() { + return objectLookupComparator(PackSource.DEFAULT_COMPARATOR); + } + + /** + * Comparator for packs when looking up objects in indexes. + * <p> + * This comparator tries to position packs in the order readers should examine + * them when looking for objects by SHA-1. The default tries to sort packs + * with more recent modification dates before older packs, and packs with + * fewer objects before packs with more objects. + * + * @param packSourceComparator + * comparator for the {@link PackSource}, used as the first step in + * comparison. + * @return comparator. + */ + public static Comparator<DfsPackDescription> objectLookupComparator( + Comparator<PackSource> packSourceComparator) { + return Comparator.comparing( + DfsPackDescription::getPackSource, packSourceComparator) + .thenComparing((a, b) -> { + PackSource as = a.getPackSource(); + PackSource bs = b.getPackSource(); + + // Tie break GC type packs by smallest first. There should be at most + // one of each source, but when multiple exist concurrent GCs may have + // run. Preferring the smaller file selects higher quality delta + // compression, placing less demand on the DfsBlockCache. + if (as == bs && isGC(as)) { + int cmp = Long.signum(a.getFileSize(PACK) - b.getFileSize(PACK)); + if (cmp != 0) { + return cmp; + } + } + + // Newer packs should sort first. + int cmp = Long.signum(b.getLastModified() - a.getLastModified()); + if (cmp != 0) { + return cmp; + } + + // Break ties on smaller index. Readers may get lucky and find + // the object they care about in the smaller index. This also pushes + // big historical packs to the end of the list, due to more objects. + return Long.signum(a.getObjectCount() - b.getObjectCount()); + }); + } + + static Comparator<DfsPackDescription> reftableComparator() { + return (a, b) -> { + // GC, COMPACT reftables first by reversing default order. + int c = PackSource.DEFAULT_COMPARATOR.reversed() + .compare(a.getPackSource(), b.getPackSource()); + if (c != 0) { + return c; + } + + // Lower maxUpdateIndex first. + c = Long.signum(a.getMaxUpdateIndex() - b.getMaxUpdateIndex()); + if (c != 0) { + return c; + } + + // Older reftable first. + return Long.signum(a.getLastModified() - b.getLastModified()); + }; + } + + static Comparator<DfsPackDescription> reuseComparator() { + return (a, b) -> { + PackSource as = a.getPackSource(); + PackSource bs = b.getPackSource(); + + if (as == bs && DfsPackDescription.isGC(as)) { + // Push smaller GC files last; these likely have higher quality + // delta compression and the contained representation should be + // favored over other files. + return Long.signum(b.getFileSize(PACK) - a.getFileSize(PACK)); + } + + // DfsPackDescription.compareTo already did a reasonable sort. + // Rely on Arrays.sort being stable, leaving equal elements. + return 0; + }; + } + private final DfsRepositoryDescription repoDesc; private final String packName; private PackSource packSource; @@ -93,11 +195,15 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { * name of the pack file. Must end with ".pack". * @param repoDesc * description of the repo containing the pack file. + * @param packSource + * the source of the pack. */ - public DfsPackDescription(DfsRepositoryDescription repoDesc, String name) { + public DfsPackDescription(DfsRepositoryDescription repoDesc, String name, + @NonNull PackSource packSource) { this.repoDesc = repoDesc; int dot = name.lastIndexOf('.'); this.packName = (dot < 0) ? name : name.substring(0, dot); + this.packSource = packSource; int extCnt = PackExt.values().length; sizeMap = new long[extCnt]; @@ -162,6 +268,7 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { * * @return the source of the pack. */ + @NonNull public PackSource getPackSource() { return packSource; } @@ -173,7 +280,7 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { * the source of the pack. * @return {@code this} */ - public DfsPackDescription setPackSource(PackSource source) { + public DfsPackDescription setPackSource(@NonNull PackSource source) { packSource = source; return this; } @@ -455,49 +562,6 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { return false; } - /** - * {@inheritDoc} - * <p> - * Sort packs according to the optimal lookup ordering. - * <p> - * This method tries to position packs in the order readers should examine - * them when looking for objects by SHA-1. The default tries to sort packs - * with more recent modification dates before older packs, and packs with - * fewer objects before packs with more objects. - */ - @Override - public int compareTo(DfsPackDescription b) { - // Cluster by PackSource, pushing UNREACHABLE_GARBAGE to the end. - PackSource as = getPackSource(); - PackSource bs = b.getPackSource(); - if (as != null && bs != null) { - int cmp = as.category - bs.category; - if (cmp != 0) - return cmp; - } - - // Tie break GC type packs by smallest first. There should be at most - // one of each source, but when multiple exist concurrent GCs may have - // run. Preferring the smaller file selects higher quality delta - // compression, placing less demand on the DfsBlockCache. - if (as != null && as == bs && isGC(as)) { - int cmp = Long.signum(getFileSize(PACK) - b.getFileSize(PACK)); - if (cmp != 0) { - return cmp; - } - } - - // Newer packs should sort first. - int cmp = Long.signum(b.getLastModified() - getLastModified()); - if (cmp != 0) - return cmp; - - // Break ties on smaller index. Readers may get lucky and find - // the object they care about in the smaller index. This also pushes - // big historical packs to the end of the list, due to more objects. - return Long.signum(getObjectCount() - b.getObjectCount()); - } - static boolean isGC(PackSource s) { switch (s) { case GC: diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java index 197114bd6b..d04709f6c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java @@ -45,7 +45,6 @@ package org.eclipse.jgit.internal.storage.dfs; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE; -import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; import java.io.IOException; @@ -66,7 +65,6 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackList; -import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl; import org.eclipse.jgit.internal.storage.file.PackBitmapIndex; import org.eclipse.jgit.internal.storage.file.PackIndex; @@ -611,26 +609,9 @@ public class DfsReader extends ObjectReader implements ObjectReuseAsIs { } } - private static final Comparator<DfsPackFile> PACK_SORT_FOR_REUSE = new Comparator<DfsPackFile>() { - @Override - public int compare(DfsPackFile af, DfsPackFile bf) { - DfsPackDescription ad = af.getPackDescription(); - DfsPackDescription bd = bf.getPackDescription(); - PackSource as = ad.getPackSource(); - PackSource bs = bd.getPackSource(); - - if (as != null && as == bs && DfsPackDescription.isGC(as)) { - // Push smaller GC files last; these likely have higher quality - // delta compression and the contained representation should be - // favored over other files. - return Long.signum(bd.getFileSize(PACK) - ad.getFileSize(PACK)); - } - - // DfsPackDescription.compareTo already did a reasonable sort. - // Rely on Arrays.sort being stable, leaving equal elements. - return 0; - } - }; + private static final Comparator<DfsPackFile> PACK_SORT_FOR_REUSE = + Comparator.comparing( + DfsPackFile::getPackDescription, DfsPackDescription.reuseComparator()); private List<DfsPackFile> sortPacksForSelectRepresentation() throws IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java index 40cfb71dde..70816307f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java @@ -45,6 +45,9 @@ package org.eclipse.jgit.internal.storage.dfs; import java.io.IOException; import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; @@ -196,7 +199,7 @@ public class DfsReftableDatabase extends DfsRefDatabase { } // Cannot be the container of an existing reference. - return table.hasRef(refName + '/'); + return table.hasRefsWithPrefix(refName + '/'); } finally { lock.unlock(); } @@ -238,7 +241,8 @@ public class DfsReftableDatabase extends DfsRefDatabase { try { Reftable table = reader(); try (RefCursor rc = ALL.equals(prefix) ? table.allRefs() - : table.seekRef(prefix)) { + : (prefix.endsWith("/") ? table.seekRefsWithPrefix(prefix) //$NON-NLS-1$ + : table.seekRef(prefix))) { while (rc.next()) { Ref ref = table.resolve(rc.getRef()); if (ref != null && ref.getObjectId() != null) { @@ -256,6 +260,29 @@ public class DfsReftableDatabase extends DfsRefDatabase { /** {@inheritDoc} */ @Override + public List<Ref> getRefsByPrefix(String prefix) throws IOException { + List<Ref> all = new ArrayList<>(); + lock.lock(); + try { + Reftable table = reader(); + try (RefCursor rc = ALL.equals(prefix) ? table.allRefs() + : table.seekRefsWithPrefix(prefix)) { + while (rc.next()) { + Ref ref = table.resolve(rc.getRef()); + if (ref != null && ref.getObjectId() != null) { + all.add(ref); + } + } + } + } finally { + lock.unlock(); + } + + return Collections.unmodifiableList(all); + } + + /** {@inheritDoc} */ + @Override public Ref peel(Ref ref) throws IOException { Ref oldLeaf = ref.getLeaf(); if (oldLeaf.isPeeled() || oldLeaf.getObjectId() == null) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsStreamKey.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsStreamKey.java index c11f696708..8793d83126 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsStreamKey.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsStreamKey.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.internal.storage.dfs; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.util.Arrays; @@ -67,7 +67,7 @@ public abstract class DfsStreamKey { */ public static DfsStreamKey of(DfsRepositoryDescription repo, String name, @Nullable PackExt ext) { - return new ByteArrayDfsStreamKey(repo, name.getBytes(CHARSET), ext); + return new ByteArrayDfsStreamKey(repo, name.getBytes(UTF_8), ext); } final int hash; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java index 662c3fef81..5b6894da9c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.reftable.ReftableConfig; import org.eclipse.jgit.lib.RefDatabase; @@ -118,10 +119,10 @@ public class InMemoryRepository extends DfsRepository { @Override protected DfsPackDescription newPack(PackSource source) { int id = packId.incrementAndGet(); - DfsPackDescription desc = new MemPack( + return new MemPack( "pack-" + id + "-" + source.name(), //$NON-NLS-1$ //$NON-NLS-2$ - getRepository().getDescription()); - return desc.setPackSource(source); + getRepository().getDescription(), + source); } @Override @@ -169,8 +170,8 @@ public class InMemoryRepository extends DfsRepository { private static class MemPack extends DfsPackDescription { final byte[][] fileMap = new byte[PackExt.values().length][]; - MemPack(String name, DfsRepositoryDescription repoDesc) { - super(repoDesc, name); + MemPack(String name, DfsRepositoryDescription repoDesc, PackSource source) { + super(repoDesc, name, source); } void put(PackExt ext, byte[] data) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableBatchRefUpdate.java index e0c056a450..47ac4ec72e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableBatchRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableBatchRefUpdate.java @@ -70,7 +70,6 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.io.BlockSource; import org.eclipse.jgit.internal.storage.pack.PackExt; -import org.eclipse.jgit.internal.storage.reftable.RefCursor; import org.eclipse.jgit.internal.storage.reftable.Reftable; import org.eclipse.jgit.internal.storage.reftable.ReftableCompactor; import org.eclipse.jgit.internal.storage.reftable.ReftableConfig; @@ -240,11 +239,7 @@ public class ReftableBatchRefUpdate extends BatchRefUpdate { private boolean checkExpected(Reftable table, List<ReceiveCommand> pending) throws IOException { for (ReceiveCommand cmd : pending) { - Ref ref; - try (RefCursor rc = table.seekRef(cmd.getRefName())) { - ref = rc.next() ? rc.getRef() : null; - } - if (!matchOld(cmd, ref)) { + if (!matchOld(cmd, table.exactRef(cmd.getRefName()))) { cmd.setResult(LOCK_FAILURE); if (isAtomic()) { ReceiveCommand.abort(pending); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java index 407061fa16..3884180e19 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java @@ -104,6 +104,7 @@ abstract class BasePackBitmapIndex extends PackBitmapIndex { r = xb.xorBitmap.bitmapContainer; if (r instanceof EWAHCompressedBitmap) { out = out.xor((EWAHCompressedBitmap) r); + out.trim(); bitmapContainer = out; return out; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java index d02888a872..5ced68646f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java @@ -480,7 +480,7 @@ public class FileRepository extends Repository { /** * {@inheritDoc} * <p> - * Objects known to exist but not expressed by {@link #getAllRefs()}. + * Objects known to exist but not expressed by {@code #getAllRefs()}. * <p> * When a repository borrows objects from another repository, it can * advertise that it safely has that other repository's references, without @@ -493,12 +493,12 @@ public class FileRepository extends Repository { } /** - * Objects known to exist but not expressed by {@link #getAllRefs()}. + * Objects known to exist but not expressed by {@code #getAllRefs()}. * <p> * When a repository borrows objects from another repository, it can * advertise that it safely has that other repository's references, without - * exposing any other details about the other repository. This may help - * a client trying to push changes avoid pushing more than it needs to. + * exposing any other details about the other repository. This may help a + * client trying to push changes avoid pushing more than it needs to. * * @param skips * Set of AlternateHandle Ids already seen 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 0ecfb2868c..7bfec3fd91 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 @@ -245,6 +245,7 @@ public class GC { * parsed */ // TODO(ms): in 5.0 change signature and return Future<Collection<PackFile>> + @SuppressWarnings("FutureReturnValueIgnored") public Collection<PackFile> gc() throws IOException, ParseException { if (!background) { return doGc(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java index 0e587ce827..82458c1acf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.internal.storage.file; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.File; import java.io.IOException; @@ -171,6 +171,6 @@ class GcLog { if (content.length() > 0) { nonEmpty = true; } - lock.write(content.getBytes(CHARSET)); + lock.write(content.getBytes(UTF_8)); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LazyObjectIdSetFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LazyObjectIdSetFile.java index c82d52e79c..3d0e9c7189 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LazyObjectIdSetFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LazyObjectIdSetFile.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.internal.storage.file; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.BufferedReader; import java.io.File; @@ -86,7 +86,7 @@ public class LazyObjectIdSetFile implements ObjectIdSet { private ObjectIdOwnerMap<Entry> load() { ObjectIdOwnerMap<Entry> r = new ObjectIdOwnerMap<>(); try (FileInputStream fin = new FileInputStream(src); - Reader rin = new InputStreamReader(fin, CHARSET); + Reader rin = new InputStreamReader(fin, UTF_8); BufferedReader br = new BufferedReader(rin)) { MutableObjectId id = new MutableObjectId(); for (String line; (line = br.readLine()) != null;) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalCachedPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalCachedPack.java index 289d89d698..e931c1f9e7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalCachedPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalCachedPack.java @@ -62,13 +62,13 @@ class LocalCachedPack extends CachedPack { LocalCachedPack(ObjectDirectory odb, List<String> packNames) { this.odb = odb; - this.packNames = packNames.toArray(new String[packNames.size()]); + this.packNames = packNames.toArray(new String[0]); } LocalCachedPack(List<PackFile> packs) { odb = null; packNames = null; - this.packs = packs.toArray(new PackFile[packs.size()]); + this.packs = packs.toArray(new PackFile[0]); } /** {@inheritDoc} */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java index 51c5702fc2..24723d850c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java @@ -938,7 +938,7 @@ public class ObjectDirectory extends FileObjectDatabase { if (list.isEmpty()) return new PackList(snapshot, NO_PACKS.packs); - final PackFile[] r = list.toArray(new PackFile[list.size()]); + final PackFile[] r = list.toArray(new PackFile[0]); Arrays.sort(r, PackFile.SORT); return new PackList(snapshot, r); } @@ -1030,7 +1030,7 @@ public class ObjectDirectory extends FileObjectDatabase { l.add(openAlternate(line)); } } - return l.toArray(new AlternateHandle[l.size()]); + return l.toArray(new AlternateHandle[0]); } private static BufferedReader open(File f) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java index 70eb10ea8f..eff7958748 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java @@ -351,6 +351,7 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex { PositionEntry entry = positionEntries.get(item); if (entry == null) throw new IllegalStateException(); + bestBitmap.trim(); return new StoredEntry(entry.namePosition, bestBitmap, bestXorOffset, item.getFlags()); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java index c04c90f22f..70695880d3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java @@ -200,6 +200,7 @@ public class PackBitmapIndexRemapper extends PackBitmapIndex for (IntIterator i = oldBitmap.getBitmap().intIterator(); i.hasNext();) inflated.set(prevToNewMapping[i.next()]); bitmap = inflated.toEWAHCompressedBitmap(); + bitmap.trim(); convertedBitmaps.add( new StoredBitmap(objectId, bitmap, null, oldBitmap.getFlags())); return bitmap; 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 6a18df86e2..de7e4b3f25 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 @@ -46,7 +46,7 @@ package org.eclipse.jgit.internal.storage.file; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.HEAD; import static org.eclipse.jgit.lib.Constants.LOGS; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH; @@ -945,7 +945,7 @@ public class RefDirectory extends RefDatabase { try (BufferedReader br = new BufferedReader(new InputStreamReader( new DigestInputStream(new FileInputStream(packedRefsFile), digest), - CHARSET))) { + UTF_8))) { try { return new PackedRefList(parsePackedRefs(br), snapshot, ObjectId.fromRaw(digest.digest())); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java index d231ccb997..f42b3a5463 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java @@ -91,7 +91,7 @@ class BaseSearch { List<ObjectToPack> edges, ObjectReader or) { progress = countingMonitor; reader = or; - baseTrees = bases.toArray(new ObjectId[bases.size()]); + baseTrees = bases.toArray(new ObjectId[0]); objectsMap = objects; edgeObjects = edges; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java index 36d6f0aebc..24af8a73ba 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java @@ -1970,7 +1970,7 @@ public class PackWriter implements AutoCloseable { byte[] pathBuf = walker.getPathBuffer(); int pathLen = walker.getPathLength(); bases.addBase(o.getType(), pathBuf, pathLen, pathHash); - filterAndAddObject(o, o.getType(), pathHash); + filterAndAddObject(o, o.getType(), pathHash, want); countingMonitor.update(1); } } else { @@ -1980,7 +1980,7 @@ public class PackWriter implements AutoCloseable { continue; if (exclude(o)) continue; - filterAndAddObject(o, o.getType(), walker.getPathHashCode()); + filterAndAddObject(o, o.getType(), walker.getPathHashCode(), want); countingMonitor.update(1); } } @@ -2013,7 +2013,7 @@ public class PackWriter implements AutoCloseable { needBitmap.remove(objectId); continue; } - filterAndAddObject(objectId, obj.getType(), 0); + filterAndAddObject(objectId, obj.getType(), 0, want); } if (thin) @@ -2075,12 +2075,14 @@ public class PackWriter implements AutoCloseable { // Adds the given object as an object to be packed, first performing // filtering on blobs at or exceeding a given size. private void filterAndAddObject(@NonNull AnyObjectId src, int type, - int pathHashCode) throws IOException { + int pathHashCode, @NonNull Set<? extends AnyObjectId> want) + throws IOException { // Check if this object needs to be rejected, doing the cheaper // checks first. boolean reject = filterBlobLimit >= 0 && type == OBJ_BLOB && + !want.contains(src) && reader.getObjectSize(src, OBJ_BLOB) > filterBlobLimit; if (!reject) { addObject(src, type, pathHashCode); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java index 38d3458cf9..99db74956c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java @@ -91,11 +91,10 @@ class PackWriterBitmapPreparer { private static final int DAY_IN_SECONDS = 24 * 60 * 60; - private static final Comparator<BitmapBuilderEntry> ORDER_BY_CARDINALITY = new Comparator<BitmapBuilderEntry>() { + private static final Comparator<RevCommit> ORDER_BY_REVERSE_TIMESTAMP = new Comparator<RevCommit>() { @Override - public int compare(BitmapBuilderEntry a, BitmapBuilderEntry b) { - return Integer.signum(a.getBuilder().cardinality() - - b.getBuilder().cardinality()); + public int compare(RevCommit a, RevCommit b) { + return Integer.signum(b.getCommitTime() - a.getCommitTime()); } }; @@ -164,154 +163,177 @@ class PackWriterBitmapPreparer { * the cache hits for clients that are close to HEAD, which is the * majority of calculations performed. */ - pm.beginTask(JGitText.get().selectingCommits, ProgressMonitor.UNKNOWN); - RevWalk rw = new RevWalk(reader); - rw.setRetainBody(false); - CommitSelectionHelper selectionHelper = setupTipCommitBitmaps(rw, - expectedCommitCount, excludeFromBitmapSelection); - pm.endTask(); - - int totCommits = selectionHelper.getCommitCount(); - BlockList<BitmapCommit> selections = new BlockList<>( - totCommits / recentCommitSpan + 1); - for (BitmapCommit reuse : selectionHelper.reusedCommits) { - selections.add(reuse); - } - - if (totCommits == 0) { - for (AnyObjectId id : selectionHelper.peeledWants) { - selections.add(new BitmapCommit(id, false, 0)); + try (RevWalk rw = new RevWalk(reader); + RevWalk rw2 = new RevWalk(reader)) { + pm.beginTask(JGitText.get().selectingCommits, + ProgressMonitor.UNKNOWN); + rw.setRetainBody(false); + CommitSelectionHelper selectionHelper = captureOldAndNewCommits(rw, + expectedCommitCount, excludeFromBitmapSelection); + pm.endTask(); + + // Add reused bitmaps from the previous GC pack's bitmap indices. + // Currently they are always fully reused, even if their spans don't + // match this run's PackConfig values. + int newCommits = selectionHelper.getCommitCount(); + BlockList<BitmapCommit> selections = new BlockList<>( + selectionHelper.reusedCommits.size() + + newCommits / recentCommitSpan + 1); + for (BitmapCommit reuse : selectionHelper.reusedCommits) { + selections.add(reuse); } - return selections; - } - pm.beginTask(JGitText.get().selectingCommits, totCommits); - int totalWants = selectionHelper.peeledWants.size(); - - for (BitmapBuilderEntry entry : selectionHelper.tipCommitBitmaps) { - BitmapBuilder bitmap = entry.getBuilder(); - int cardinality = bitmap.cardinality(); - - // Within this branch, keep ordered lists of commits representing - // chains in its history, where each chain is a "sub-branch". - // Ordering commits by these chains makes for fewer differences - // between consecutive selected commits, which in turn provides - // better compression/on the run-length encoding of the XORs between - // them. - List<List<BitmapCommit>> chains = - new ArrayList<>(); - - // Mark the current branch as inactive if its tip commit isn't - // recent and there are an excessive number of branches, to - // prevent memory bloat of computing too many bitmaps for stale - // branches. - boolean isActiveBranch = true; - if (totalWants > excessiveBranchCount - && !isRecentCommit(entry.getCommit())) { - isActiveBranch = false; + if (newCommits == 0) { + for (AnyObjectId id : selectionHelper.newWants) { + selections.add(new BitmapCommit(id, false, 0)); + } + return selections; } - // Insert bitmaps at the offsets suggested by the - // nextSelectionDistance() heuristic. Only reuse bitmaps created - // for more distant commits. - int index = -1; - int nextIn = nextSpan(cardinality); - int nextFlg = nextIn == distantCommitSpan - ? PackBitmapIndex.FLAG_REUSE : 0; - - // For the current branch, iterate through all commits from oldest - // to newest. - for (RevCommit c : selectionHelper) { - // Optimization: if we have found all the commits for this - // branch, stop searching - int distanceFromTip = cardinality - index - 1; - if (distanceFromTip == 0) { - break; + pm.beginTask(JGitText.get().selectingCommits, newCommits); + int totalWants = want.size(); + BitmapBuilder seen = commitBitmapIndex.newBitmapBuilder(); + seen.or(selectionHelper.reusedCommitsBitmap); + rw2.setRetainBody(false); + rw2.setRevFilter(new NotInBitmapFilter(seen)); + + // For each branch, do a revwalk to enumerate its commits. Exclude + // both reused commits and any commits seen in a previous branch. + // Then iterate through all new commits from oldest to newest, + // selecting well-spaced commits in this branch. + for (RevCommit rc : selectionHelper.newWantsByNewest) { + BitmapBuilder tipBitmap = commitBitmapIndex.newBitmapBuilder(); + rw2.markStart((RevCommit) rw2.peel(rw2.parseAny(rc))); + RevCommit rc2; + while ((rc2 = rw2.next()) != null) { + tipBitmap.addObject(rc2, Constants.OBJ_COMMIT); } - - // Ignore commits that are not in this branch - if (!bitmap.contains(c)) { - continue; + int cardinality = tipBitmap.cardinality(); + seen.or(tipBitmap); + + // Within this branch, keep ordered lists of commits + // representing chains in its history, where each chain is a + // "sub-branch". Ordering commits by these chains makes for + // fewer differences between consecutive selected commits, which + // in turn provides better compression/on the run-length + // encoding of the XORs between them. + List<List<BitmapCommit>> chains = new ArrayList<>(); + + // Mark the current branch as inactive if its tip commit isn't + // recent and there are an excessive number of branches, to + // prevent memory bloat of computing too many bitmaps for stale + // branches. + boolean isActiveBranch = true; + if (totalWants > excessiveBranchCount && !isRecentCommit(rc)) { + isActiveBranch = false; } - index++; - nextIn--; - pm.update(1); - - // Always pick the items in wants, prefer merge commits. - if (selectionHelper.peeledWants.remove(c)) { - if (nextIn > 0) { - nextFlg = 0; + // Insert bitmaps at the offsets suggested by the + // nextSelectionDistance() heuristic. Only reuse bitmaps created + // for more distant commits. + int index = -1; + int nextIn = nextSpan(cardinality); + int nextFlg = nextIn == distantCommitSpan + ? PackBitmapIndex.FLAG_REUSE + : 0; + + // For the current branch, iterate through all commits from + // oldest to newest. + for (RevCommit c : selectionHelper) { + // Optimization: if we have found all the commits for this + // branch, stop searching + int distanceFromTip = cardinality - index - 1; + if (distanceFromTip == 0) { + break; } - } else { - boolean stillInSpan = nextIn >= 0; - boolean isMergeCommit = c.getParentCount() > 1; - // Force selection if: - // a) we have exhausted the window looking for merges - // b) we are in the top commits of an active branch - // c) we are at a branch tip - boolean mustPick = (nextIn <= -recentCommitSpan) - || (isActiveBranch - && (distanceFromTip <= contiguousCommitCount)) - || (distanceFromTip == 1); // most recent commit - if (!mustPick && (stillInSpan || !isMergeCommit)) { + + // Ignore commits that are not in this branch + if (!tipBitmap.contains(c)) { continue; } - } - // This commit is selected. - // Calculate where to look for the next one. - int flags = nextFlg; - nextIn = nextSpan(distanceFromTip); - nextFlg = nextIn == distantCommitSpan - ? PackBitmapIndex.FLAG_REUSE : 0; - - BitmapBuilder fullBitmap = commitBitmapIndex.newBitmapBuilder(); - rw.reset(); - rw.markStart(c); - rw.setRevFilter(new AddUnseenToBitmapFilter( - selectionHelper.reusedCommitsBitmap, fullBitmap)); - - while (rw.next() != null) { - // The RevFilter adds the reachable commits from this - // selected commit to fullBitmap. - } + index++; + nextIn--; + pm.update(1); - // Sort the commits by independent chains in this branch's - // history, yielding better compression when building bitmaps. - List<BitmapCommit> longestAncestorChain = null; - for (List<BitmapCommit> chain : chains) { - BitmapCommit mostRecentCommit = chain.get(chain.size() - 1); - if (fullBitmap.contains(mostRecentCommit)) { - if (longestAncestorChain == null - || longestAncestorChain.size() < chain.size()) { - longestAncestorChain = chain; + // Always pick the items in wants, prefer merge commits. + if (selectionHelper.newWants.remove(c)) { + if (nextIn > 0) { + nextFlg = 0; + } + } else { + boolean stillInSpan = nextIn >= 0; + boolean isMergeCommit = c.getParentCount() > 1; + // Force selection if: + // a) we have exhausted the window looking for merges + // b) we are in the top commits of an active branch + // c) we are at a branch tip + boolean mustPick = (nextIn <= -recentCommitSpan) + || (isActiveBranch + && (distanceFromTip <= contiguousCommitCount)) + || (distanceFromTip == 1); // most recent commit + if (!mustPick && (stillInSpan || !isMergeCommit)) { + continue; } } + + // This commit is selected. + // Calculate where to look for the next one. + int flags = nextFlg; + nextIn = nextSpan(distanceFromTip); + nextFlg = nextIn == distantCommitSpan + ? PackBitmapIndex.FLAG_REUSE + : 0; + + // Create the commit bitmap for the current commit + BitmapBuilder bitmap = commitBitmapIndex.newBitmapBuilder(); + rw.reset(); + rw.markStart(c); + rw.setRevFilter(new AddUnseenToBitmapFilter( + selectionHelper.reusedCommitsBitmap, bitmap)); + while (rw.next() != null) { + // The filter adds the reachable commits to bitmap. + } + + // Sort the commits by independent chains in this branch's + // history, yielding better compression when building + // bitmaps. + List<BitmapCommit> longestAncestorChain = null; + for (List<BitmapCommit> chain : chains) { + BitmapCommit mostRecentCommit = chain + .get(chain.size() - 1); + if (bitmap.contains(mostRecentCommit)) { + if (longestAncestorChain == null + || longestAncestorChain.size() < chain + .size()) { + longestAncestorChain = chain; + } + } + } + + if (longestAncestorChain == null) { + longestAncestorChain = new ArrayList<>(); + chains.add(longestAncestorChain); + } + longestAncestorChain.add(new BitmapCommit(c, + !longestAncestorChain.isEmpty(), flags)); + writeBitmaps.addBitmap(c, bitmap, 0); } - if (longestAncestorChain == null) { - longestAncestorChain = new ArrayList<>(); - chains.add(longestAncestorChain); + for (List<BitmapCommit> chain : chains) { + selections.addAll(chain); } - longestAncestorChain.add(new BitmapCommit( - c, !longestAncestorChain.isEmpty(), flags)); - writeBitmaps.addBitmap(c, fullBitmap, 0); } + writeBitmaps.clearBitmaps(); // Remove the temporary commit bitmaps. - for (List<BitmapCommit> chain : chains) { - selections.addAll(chain); + // Add the remaining peeledWant + for (AnyObjectId remainingWant : selectionHelper.newWants) { + selections.add(new BitmapCommit(remainingWant, false, 0)); } - } - writeBitmaps.clearBitmaps(); // Remove the temporary commit bitmaps. - // Add the remaining peeledWant - for (AnyObjectId remainingWant : selectionHelper.peeledWants) { - selections.add(new BitmapCommit(remainingWant, false, 0)); + pm.endTask(); + return selections; } - - pm.endTask(); - return selections; } private boolean isRecentCommit(RevCommit revCommit) { @@ -358,9 +380,8 @@ class PackWriterBitmapPreparer { } /** - * For each of the {@code want}s, which represent the tip commit of each - * branch, set up an initial {@link BitmapBuilder}. Reuse previously built - * bitmaps if possible. + * Records which of the {@code wants} can be found in the previous GC pack's + * bitmap indices and which are new. * * @param rw * a {@link RevWalk} to find reachable objects in this repository @@ -369,8 +390,9 @@ class PackWriterBitmapPreparer { * unreachable garbage. * @param excludeFromBitmapSelection * commits that should be excluded from bitmap selection - * @return a {@link CommitSelectionHelper} containing bitmaps for the tip - * commits + * @return a {@link CommitSelectionHelper} capturing which commits are + * covered by a previous pack's bitmaps and which new commits need + * bitmap coverage * @throws IncorrectObjectTypeException * if any of the processed objects is not a commit * @throws IOException @@ -378,11 +400,12 @@ class PackWriterBitmapPreparer { * @throws MissingObjectException * if an expected object is missing */ - private CommitSelectionHelper setupTipCommitBitmaps(RevWalk rw, + private CommitSelectionHelper captureOldAndNewCommits(RevWalk rw, int expectedCommitCount, Set<? extends ObjectId> excludeFromBitmapSelection) throws IncorrectObjectTypeException, IOException, MissingObjectException { + // Track bitmaps and commits from the previous GC pack bitmap indices. BitmapBuilder reuse = commitBitmapIndex.newBitmapBuilder(); List<BitmapCommit> reuseCommits = new ArrayList<>(); for (PackBitmapIndexRemapper.Entry entry : bitmapRemapper) { @@ -404,11 +427,10 @@ class PackWriterBitmapPreparer { } } - // Add branch tips that are not represented in old bitmap indices. Set - // up the RevWalk to walk the new commits not in the old packs. - List<BitmapBuilderEntry> tipCommitBitmaps = new ArrayList<>( - want.size()); - Set<RevCommit> peeledWant = new HashSet<>(want.size()); + // Add branch tips that are not represented in a previous pack's bitmap + // indices. Set up a RevWalk to find new commits not in the old packs. + List<RevCommit> newWantsByNewest = new ArrayList<>(want.size()); + Set<RevCommit> newWants = new HashSet<>(want.size()); for (AnyObjectId objectId : want) { RevObject ro = rw.peel(rw.parseAny(objectId)); if (!(ro instanceof RevCommit) || reuse.contains(ro) @@ -417,59 +439,26 @@ class PackWriterBitmapPreparer { } RevCommit rc = (RevCommit) ro; - peeledWant.add(rc); rw.markStart(rc); - - BitmapBuilder bitmap = commitBitmapIndex.newBitmapBuilder(); - bitmap.addObject(rc, Constants.OBJ_COMMIT); - tipCommitBitmaps.add(new BitmapBuilderEntry(rc, bitmap)); + newWants.add(rc); + newWantsByNewest.add(rc); } - // Create a list of commits in reverse order (older to newer). - // For each branch that contains the commit, mark its parents as being - // in the bitmap. + // Create a list of commits in reverse order (older to newer) that are + // not in the previous bitmap indices and are reachable. rw.setRevFilter(new NotInBitmapFilter(reuse)); RevCommit[] commits = new RevCommit[expectedCommitCount]; int pos = commits.length; RevCommit rc; while ((rc = rw.next()) != null && pos > 0) { commits[--pos] = rc; - for (BitmapBuilderEntry entry : tipCommitBitmaps) { - BitmapBuilder bitmap = entry.getBuilder(); - if (!bitmap.contains(rc)) { - continue; - } - for (RevCommit c : rc.getParents()) { - if (reuse.contains(c)) { - continue; - } - bitmap.addObject(c, Constants.OBJ_COMMIT); - } - } pm.update(1); } - // Sort the tip commit bitmaps. Find the one containing the most - // commits, remove those commits from the remaining bitmaps, resort and - // repeat. - List<BitmapBuilderEntry> orderedTipCommitBitmaps = new ArrayList<>( - tipCommitBitmaps.size()); - while (!tipCommitBitmaps.isEmpty()) { - BitmapBuilderEntry largest = - Collections.max(tipCommitBitmaps, ORDER_BY_CARDINALITY); - tipCommitBitmaps.remove(largest); - orderedTipCommitBitmaps.add(largest); - - // Update the remaining paths, by removing the objects from - // the path that was just added. - for (int i = tipCommitBitmaps.size() - 1; i >= 0; i--) { - tipCommitBitmaps.get(i).getBuilder() - .andNot(largest.getBuilder()); - } - } - - return new CommitSelectionHelper(peeledWant, commits, pos, - orderedTipCommitBitmaps, reuse, reuseCommits); + // Sort the new wants by reverse commit time. + Collections.sort(newWantsByNewest, ORDER_BY_REVERSE_TIMESTAMP); + return new CommitSelectionHelper(newWants, commits, pos, + newWantsByNewest, reuse, reuseCommits); } /*- @@ -537,54 +526,36 @@ class PackWriterBitmapPreparer { } /** - * A POJO representing a Pair<RevCommit, BitmapBuidler>. - */ - private static final class BitmapBuilderEntry { - private final RevCommit commit; - private final BitmapBuilder builder; - - BitmapBuilderEntry(RevCommit commit, BitmapBuilder builder) { - this.commit = commit; - this.builder = builder; - } - - RevCommit getCommit() { - return commit; - } - - BitmapBuilder getBuilder() { - return builder; - } - } - - /** * Container for state used in the first phase of selecting commits, which - * walks all of the reachable commits via the branch tips ( - * {@code peeledWants}), stores them in {@code commitsByOldest}, and sets up - * bitmaps for each branch tip ({@code tipCommitBitmaps}). - * {@code commitsByOldest} is initialized with an expected size of all - * commits, but may be smaller if some commits are unreachable, in which - * case {@code commitStartPos} will contain a positive offset to the root - * commit. + * walks all of the reachable commits via the branch tips that are not + * covered by a previous pack's bitmaps ({@code newWants}) and stores them + * in {@code newCommitsByOldest}. {@code newCommitsByOldest} is initialized + * with an expected size of all commits, but may be smaller if some commits + * are unreachable and/or some commits are covered by a previous pack's + * bitmaps. {@code commitStartPos} will contain a positive offset to either + * the root commit or the oldest commit not covered by previous bitmaps. */ private static final class CommitSelectionHelper implements Iterable<RevCommit> { - final Set<? extends ObjectId> peeledWants; - final List<BitmapBuilderEntry> tipCommitBitmaps; + final Set<? extends ObjectId> newWants; + final List<RevCommit> newWantsByNewest; final BitmapBuilder reusedCommitsBitmap; - final Iterable<BitmapCommit> reusedCommits; - final RevCommit[] commitsByOldest; - final int commitStartPos; - CommitSelectionHelper(Set<? extends ObjectId> peeledWant, + final List<BitmapCommit> reusedCommits; + + final RevCommit[] newCommitsByOldest; + + final int newCommitStartPos; + + CommitSelectionHelper(Set<? extends ObjectId> newWants, RevCommit[] commitsByOldest, int commitStartPos, - List<BitmapBuilderEntry> bitmapEntries, + List<RevCommit> newWantsByNewest, BitmapBuilder reusedCommitsBitmap, - Iterable<BitmapCommit> reuse) { - this.peeledWants = peeledWant; - this.commitsByOldest = commitsByOldest; - this.commitStartPos = commitStartPos; - this.tipCommitBitmaps = bitmapEntries; + List<BitmapCommit> reuse) { + this.newWants = newWants; + this.newCommitsByOldest = commitsByOldest; + this.newCommitStartPos = commitStartPos; + this.newWantsByNewest = newWantsByNewest; this.reusedCommitsBitmap = reusedCommitsBitmap; this.reusedCommits = reuse; } @@ -594,16 +565,16 @@ class PackWriterBitmapPreparer { // Member variables referenced by this iterator will have synthetic // accessors generated for them if they are made private. return new Iterator<RevCommit>() { - int pos = commitStartPos; + int pos = newCommitStartPos; @Override public boolean hasNext() { - return pos < commitsByOldest.length; + return pos < newCommitsByOldest.length; } @Override public RevCommit next() { - return commitsByOldest[pos++]; + return newCommitsByOldest[pos++]; } @Override @@ -614,7 +585,7 @@ class PackWriterBitmapPreparer { } int getCommitCount() { - return commitsByOldest.length - commitStartPos; + return newCommitsByOldest.length - newCommitStartPos; } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java index 942d72fe23..ce2ba4a2e1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.internal.storage.reftable; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.internal.storage.reftable.BlockWriter.compare; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.FILE_BLOCK_TYPE; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.FILE_HEADER_LEN; @@ -138,7 +138,7 @@ class BlockReader { if (blockType == LOG_BLOCK_TYPE) { len -= 9; } - return RawParseUtils.decode(CHARSET, nameBuf, 0, len); + return RawParseUtils.decode(UTF_8, nameBuf, 0, len); } boolean match(byte[] match, boolean matchIsPrefix) { @@ -171,7 +171,7 @@ class BlockReader { } Ref readRef() throws IOException { - String name = RawParseUtils.decode(CHARSET, nameBuf, 0, nameLen); + String name = RawParseUtils.decode(UTF_8, nameBuf, 0, nameLen); switch (valueType & VALUE_TYPE_MASK) { case VALUE_NONE: // delete return newRef(name); @@ -266,7 +266,7 @@ class BlockReader { private String readValueString() { int len = readVarint32(); int end = ptr + len; - String s = RawParseUtils.decode(CHARSET, buf, ptr, end); + String s = RawParseUtils.decode(UTF_8, buf, ptr, end); ptr = end; return s; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java index 3d8fbf4996..b3173e838c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.internal.storage.reftable; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.FILE_HEADER_LEN; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.INDEX_BLOCK_TYPE; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.LOG_BLOCK_TYPE; @@ -440,7 +440,7 @@ class BlockWriter { } private static byte[] nameUtf8(Ref ref) { - return ref.getName().getBytes(CHARSET); + return ref.getName().getBytes(UTF_8); } } @@ -559,13 +559,13 @@ class BlockWriter { this.newId = newId; this.timeSecs = who.getWhen().getTime() / 1000L; this.tz = (short) who.getTimeZoneOffset(); - this.name = who.getName().getBytes(CHARSET); - this.email = who.getEmailAddress().getBytes(CHARSET); - this.msg = message.getBytes(CHARSET); + this.name = who.getName().getBytes(UTF_8); + this.email = who.getEmailAddress().getBytes(UTF_8); + this.msg = message.getBytes(UTF_8); } static byte[] key(String ref, long index) { - byte[] name = ref.getBytes(CHARSET); + byte[] name = ref.getBytes(UTF_8); byte[] key = Arrays.copyOf(name, name.length + 1 + 8); NB.encodeInt64(key, key.length - 8, reverseUpdateIndex(index)); return key; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java index ef686a3008..17894b1664 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java @@ -113,6 +113,16 @@ public class MergedReftable extends Reftable { /** {@inheritDoc} */ @Override + public RefCursor seekRefsWithPrefix(String prefix) throws IOException { + MergedRefCursor m = new MergedRefCursor(); + for (int i = 0; i < tables.length; i++) { + m.add(new RefQueueEntry(tables[i].seekRefsWithPrefix(prefix), i)); + } + return m; + } + + /** {@inheritDoc} */ + @Override public RefCursor byObjectId(AnyObjectId name) throws IOException { MergedRefCursor m = new MergedRefCursor(); for (int i = 0; i < tables.length; i++) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java index 510c1a14e0..a1087e2023 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java @@ -108,18 +108,14 @@ public abstract class Reftable implements AutoCloseable { public abstract RefCursor allRefs() throws IOException; /** - * Seek either to a reference, or a reference subtree. + * Seek to a reference. * <p> - * If {@code refName} ends with {@code "/"} the method will seek to the - * subtree of all references starting with {@code refName} as a prefix. If - * no references start with this prefix, an empty cursor is returned. - * <p> - * Otherwise exactly {@code refName} will be looked for. If present, the + * This method will seek to the reference {@code refName}. If present, the * returned cursor will iterate exactly one entry. If not found, an empty * cursor is returned. * * @param refName - * reference name or subtree to find. + * reference name. * @return cursor to iterate; empty cursor if no references match. * @throws java.io.IOException * if references cannot be read. @@ -127,6 +123,21 @@ public abstract class Reftable implements AutoCloseable { public abstract RefCursor seekRef(String refName) throws IOException; /** + * Seek references with prefix. + * <p> + * The method will seek all the references starting with {@code prefix} as a + * prefix. If no references start with this prefix, an empty cursor is + * returned. + * + * @param prefix + * prefix to find. + * @return cursor to iterate; empty cursor if no references match. + * @throws java.io.IOException + * if references cannot be read. + */ + public abstract RefCursor seekRefsWithPrefix(String prefix) throws IOException; + + /** * Match references pointing to a specific object. * * @param id @@ -191,17 +202,11 @@ public abstract class Reftable implements AutoCloseable { } /** - * Test if a reference or reference subtree exists. - * <p> - * If {@code refName} ends with {@code "/"}, the method tests if any - * reference starts with {@code refName} as a prefix. - * <p> - * Otherwise, the method checks if {@code refName} exists. + * Test if a reference exists. * * @param refName * reference name or subtree to find. - * @return {@code true} if the reference exists, or at least one reference - * exists in the subtree. + * @return {@code true} if the reference exists. * @throws java.io.IOException * if references cannot be read. */ @@ -212,6 +217,21 @@ public abstract class Reftable implements AutoCloseable { } /** + * Test if any reference starts with {@code prefix} as a prefix. + * + * @param prefix + * prefix to find. + * @return {@code true} if at least one reference exists with prefix. + * @throws java.io.IOException + * if references cannot be read. + */ + public boolean hasRefsWithPrefix(String prefix) throws IOException { + try (RefCursor rc = seekRefsWithPrefix(prefix)) { + return rc.next(); + } + } + + /** * Test if any reference directly refers to the object. * * @param id diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableOutputStream.java index 44bbb16219..1fc43c9fac 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableOutputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableOutputStream.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.internal.storage.reftable; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.FILE_HEADER_LEN; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.INDEX_BLOCK_TYPE; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.LOG_BLOCK_TYPE; @@ -160,7 +160,7 @@ class ReftableOutputStream extends OutputStream { } void writeVarintString(String s) { - writeVarintString(s.getBytes(CHARSET)); + writeVarintString(s.getBytes(UTF_8)); } void writeVarintString(byte[] msg) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java index 5356952b5d..81b30e4cb9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.internal.storage.reftable; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.internal.storage.reftable.BlockReader.decodeBlockLen; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.FILE_BLOCK_TYPE; import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.FILE_FOOTER_LEN; @@ -182,10 +182,19 @@ public class ReftableReader extends Reftable { public RefCursor seekRef(String refName) throws IOException { initRefIndex(); - byte[] key = refName.getBytes(CHARSET); - boolean prefix = key[key.length - 1] == '/'; + byte[] key = refName.getBytes(UTF_8); + RefCursorImpl i = new RefCursorImpl(refEnd, key, false); + i.block = seek(REF_BLOCK_TYPE, key, refIndex, 0, refEnd); + return i; + } + + /** {@inheritDoc} */ + @Override + public RefCursor seekRefsWithPrefix(String prefix) throws IOException { + initRefIndex(); - RefCursorImpl i = new RefCursorImpl(refEnd, key, prefix); + byte[] key = prefix.getBytes(UTF_8); + RefCursorImpl i = new RefCursorImpl(refEnd, key, true); i.block = seek(REF_BLOCK_TYPE, key, refIndex, 0, refEnd); return i; } @@ -223,7 +232,7 @@ public class ReftableReader extends Reftable { initLogIndex(); if (logPosition > 0) { byte[] key = LogEntry.key(refName, updateIndex); - byte[] match = refName.getBytes(CHARSET); + byte[] match = refName.getBytes(UTF_8); LogCursorImpl i = new LogCursorImpl(logEnd, match); i.block = seek(LOG_BLOCK_TYPE, key, logIndex, logPosition, logEnd); return i; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java index 2c7c6cb060..d1cf1cd9ae 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java @@ -283,7 +283,7 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re final List<File> alts = alternateObjectDirectories; if (alts == null) return null; - return alts.toArray(new File[alts.size()]); + return alts.toArray(new File[0]); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java index e008be3a3c..59154b78bf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.lib; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.FileNotFoundException; import java.io.IOException; @@ -83,7 +83,7 @@ public class BlobBasedConfig extends Config { super(base); final String decoded; if (isUtf8(blob)) { - decoded = RawParseUtils.decode(CHARSET, blob, 3, blob.length); + decoded = RawParseUtils.decode(UTF_8, blob, 3, blob.length); } else { decoded = RawParseUtils.decode(blob); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java index 59a13f6550..c30833d0a6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java @@ -45,6 +45,8 @@ package org.eclipse.jgit.lib; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; @@ -93,7 +95,7 @@ public class CommitBuilder { */ public CommitBuilder() { parentIds = EMPTY_OBJECTID_LIST; - encoding = Constants.CHARSET; + encoding = UTF_8; } /** @@ -314,7 +316,7 @@ public class CommitBuilder { w.flush(); os.write('\n'); - if (getEncoding() != Constants.CHARSET) { + if (getEncoding() != UTF_8) { os.write(hencoding); os.write(' '); os.write(Constants.encodeASCII(getEncoding().name())); @@ -375,7 +377,7 @@ public class CommitBuilder { r.append(committer != null ? committer.toString() : "NOT_SET"); r.append("\n"); - if (encoding != null && encoding != Constants.CHARSET) { + if (encoding != null && encoding != UTF_8) { r.append("encoding "); r.append(encoding.name()); r.append("\n"); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java index 0e01cca99b..b666f21d0b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java @@ -51,7 +51,7 @@ package org.eclipse.jgit.lib; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.text.MessageFormat; import java.util.ArrayList; @@ -1168,7 +1168,7 @@ public class Config { String decoded; if (isUtf8(bytes)) { - decoded = RawParseUtils.decode(CHARSET, bytes, 3, bytes.length); + decoded = RawParseUtils.decode(UTF_8, bytes, 3, bytes.length); } else { decoded = RawParseUtils.decode(bytes); } 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 5a790350b1..d4a0280da6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java @@ -49,7 +49,7 @@ package org.eclipse.jgit.lib; * configuration keys */ @SuppressWarnings("nls") -public class ConfigConstants { +public final class ConfigConstants { /** The "core" section */ public static final String CONFIG_CORE_SECTION = "core"; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java index 9023bd8610..ed0055416b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java @@ -227,7 +227,13 @@ public final class Constants { */ public static final byte[] PACK_SIGNATURE = { 'P', 'A', 'C', 'K' }; - /** Native character encoding for commit messages, file names... */ + /** + * Native character encoding for commit messages, file names... + * + * @deprecated Use {@link java.nio.charset.StandardCharsets#UTF_8} directly + * instead. + **/ + @Deprecated public static final Charset CHARSET; /** Native character encoding for commit messages, file names... */ @@ -638,7 +644,7 @@ public final class Constants { * @see #CHARACTER_ENCODING */ public static byte[] encode(String str) { - final ByteBuffer bb = Constants.CHARSET.encode(str); + final ByteBuffer bb = UTF_8.encode(str); final int len = bb.limit(); if (bb.hasArray() && bb.arrayOffset() == 0) { final byte[] arr = bb.array(); @@ -655,7 +661,7 @@ public final class Constants { if (OBJECT_ID_LENGTH != newMessageDigest().getDigestLength()) throw new LinkageError(JGitText.get().incorrectOBJECT_ID_LENGTH); CHARSET = UTF_8; - CHARACTER_ENCODING = CHARSET.name(); + CHARACTER_ENCODING = UTF_8.name(); } /** name of the file containing the commit msg for a merge commit */ @@ -687,11 +693,23 @@ public final class Constants { */ public static final String COMMIT_EDITMSG = "COMMIT_EDITMSG"; - /** objectid for the empty blob */ + /** + * Well-known object ID for the empty blob. + * + * @since 0.9.1 + */ public static final ObjectId EMPTY_BLOB_ID = ObjectId .fromString("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"); /** + * Well-known object ID for the empty tree. + * + * @since 5.1 + */ + public static final ObjectId EMPTY_TREE_ID = ObjectId + .fromString("4b825dc642cb6eb9a060e54bf8d69288fbee4904"); + + /** * Suffix of lock file name * * @since 4.7 diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java index 38716055b5..06b4b227c8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.lib; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.BufferedOutputStream; import java.io.File; @@ -183,7 +183,7 @@ public class RebaseTodoFile { switch (tokenCount) { case 0: String actionToken = new String(buf, tokenBegin, - nextSpace - tokenBegin - 1, CHARSET); + nextSpace - tokenBegin - 1, UTF_8); tokenBegin = nextSpace; action = RebaseTodoLine.Action.parse(actionToken); if (action == null) @@ -192,7 +192,7 @@ public class RebaseTodoFile { case 1: nextSpace = RawParseUtils.next(buf, tokenBegin, ' '); String commitToken = new String(buf, tokenBegin, - nextSpace - tokenBegin - 1, CHARSET); + nextSpace - tokenBegin - 1, UTF_8); tokenBegin = nextSpace; commit = AbbreviatedObjectId.fromString(commitToken); break; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index 29cc19c43c..d73c05e243 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -1094,7 +1094,9 @@ public abstract class Repository implements AutoCloseable { * not point to any object yet. * * @return mutable map of all known refs (heads, tags, remotes). + * @deprecated use {@code getRefDatabase().getRefs()} instead. */ + @Deprecated @NonNull public Map<String, Ref> getAllRefs() { try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TagBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TagBuilder.java index bd03165805..7669e95acc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TagBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TagBuilder.java @@ -45,6 +45,8 @@ package org.eclipse.jgit.lib; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; @@ -181,7 +183,7 @@ public class TagBuilder { public byte[] build() { ByteArrayOutputStream os = new ByteArrayOutputStream(); try (OutputStreamWriter w = new OutputStreamWriter(os, - Constants.CHARSET)) { + UTF_8)) { w.write("object "); //$NON-NLS-1$ getObjectId().copyTo(w); w.write('\n'); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java index 2f759e53ca..936ce3dcc8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.lib; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.io.OutputStreamWriter; @@ -63,7 +63,7 @@ public class TextProgressMonitor extends BatchingProgressMonitor { * Initialize a new progress monitor. */ public TextProgressMonitor() { - this(new PrintWriter(new OutputStreamWriter(System.err, CHARSET))); + this(new PrintWriter(new OutputStreamWriter(System.err, UTF_8))); } /** 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 da6a3da67d..f60c95f647 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -78,6 +78,7 @@ 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.DirCacheEntry; import org.eclipse.jgit.errors.BinaryBlobException; import org.eclipse.jgit.errors.CorruptObjectException; @@ -297,6 +298,12 @@ public class ResolveMerger extends ThreeWayMerger { */ private int inCoreLimit; + /** + * Keeps {@link CheckoutMetadata} for {@link #checkout()} and + * {@link #cleanUp()}. + */ + private Map<String, CheckoutMetadata> checkoutMetadata; + private static MergeAlgorithm getMergeAlgorithm(Config config) { SupportedAlgorithm diffAlg = config.getEnum( CONFIG_DIFF_SECTION, null, CONFIG_KEY_ALGORITHM, @@ -313,6 +320,8 @@ public class ResolveMerger extends ThreeWayMerger { return new String[] { "BASE", "OURS", "THEIRS" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } + private static final Attributes NO_ATTRIBUTES = new Attributes(); + /** * Constructor for ResolveMerger. * @@ -369,15 +378,20 @@ public class ResolveMerger extends ThreeWayMerger { /** {@inheritDoc} */ @Override protected boolean mergeImpl() throws IOException { - if (implicitDirCache) + if (implicitDirCache) { dircache = nonNullRepo().lockDirCache(); - + } + if (!inCore) { + checkoutMetadata = new HashMap<>(); + } try { return mergeTrees(mergeBase(), sourceTrees[0], sourceTrees[1], false); } finally { - if (implicitDirCache) + checkoutMetadata = null; + if (implicitDirCache) { dircache.unlock(); + } } } @@ -400,7 +414,8 @@ public class ResolveMerger extends ThreeWayMerger { if (cacheEntry.getFileMode() == FileMode.GITLINK) { new File(nonNullRepo().getWorkTree(), entry.getKey()).mkdirs(); } else { - DirCacheCheckout.checkoutEntry(db, cacheEntry, reader); + DirCacheCheckout.checkoutEntry(db, cacheEntry, reader, false, + checkoutMetadata.get(entry.getKey())); modifiedFiles.add(entry.getKey()); } } @@ -428,10 +443,12 @@ public class ResolveMerger extends ThreeWayMerger { DirCache dc = nonNullRepo().readDirCache(); Iterator<String> mpathsIt=modifiedFiles.iterator(); while(mpathsIt.hasNext()) { - String mpath=mpathsIt.next(); + String mpath = mpathsIt.next(); DirCacheEntry entry = dc.getEntry(mpath); - if (entry != null) - DirCacheCheckout.checkoutEntry(db, entry, reader); + if (entry != null) { + DirCacheCheckout.checkoutEntry(db, entry, reader, false, + checkoutMetadata.get(mpath)); + } mpathsIt.remove(); } } @@ -481,6 +498,71 @@ public class ResolveMerger extends ThreeWayMerger { } /** + * Remembers the {@link CheckoutMetadata} for the given path; it may be + * needed in {@link #checkout()} or in {@link #cleanUp()}. + * + * @param path + * of the current node + * @param attributes + * for the current node + * @throws IOException + * if the smudge filter cannot be determined + * @since 5.1 + */ + protected void addCheckoutMetadata(String path, Attributes attributes) + throws IOException { + if (checkoutMetadata != null) { + EolStreamType eol = EolStreamTypeUtil.detectStreamType( + OperationType.CHECKOUT_OP, workingTreeOptions, attributes); + CheckoutMetadata data = new CheckoutMetadata(eol, + tw.getFilterCommand(Constants.ATTR_FILTER_TYPE_SMUDGE)); + checkoutMetadata.put(path, data); + } + } + + /** + * Adds a {@link DirCacheEntry} for direct checkout and remembers its + * {@link CheckoutMetadata}. + * + * @param path + * of the entry + * @param entry + * to add + * @param attributes + * for the current entry + * @throws IOException + * if the {@link CheckoutMetadata} cannot be determined + * @since 5.1 + */ + protected void addToCheckout(String path, DirCacheEntry entry, + Attributes attributes) throws IOException { + toBeCheckedOut.put(path, entry); + addCheckoutMetadata(path, attributes); + } + + /** + * Remember a path for deletion, and remember its {@link CheckoutMetadata} + * in case it has to be restored in {@link #cleanUp()}. + * + * @param path + * of the entry + * @param isFile + * whether it is a file + * @param attributes + * for the entry + * @throws IOException + * if the {@link CheckoutMetadata} cannot be determined + * @since 5.1 + */ + protected void addDeletion(String path, boolean isFile, + Attributes attributes) throws IOException { + toBeDeleted.add(path); + if (isFile) { + addCheckoutMetadata(path, attributes); + } + } + + /** * Processes one path and tries to merge taking git attributes in account. * This method will do all trivial (not content) merges and will also detect * if a merge will fail. The merge will fail when one of the following is @@ -586,7 +668,7 @@ public class ResolveMerger extends ThreeWayMerger { // This will happen later. Set these values to 0 for know. DirCacheEntry e = add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_0, 0, 0); - toBeCheckedOut.put(tw.getPathString(), e); + addToCheckout(tw.getPathString(), e, attributes); } return true; } else { @@ -627,18 +709,23 @@ public class ResolveMerger extends ThreeWayMerger { // This will happen later. Set these values to 0 for know. DirCacheEntry e = add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_0, 0, 0); - if (e != null) - toBeCheckedOut.put(tw.getPathString(), e); + if (e != null) { + addToCheckout(tw.getPathString(), e, attributes); + } return true; } else { // we want THEIRS ... but THEIRS contains a folder or the - // deletion of the path. Delete what's in the workingtree (the - // workingtree is clean) but do not complain if the file is - // already deleted locally. This complements the test in - // isWorktreeDirty() for the same case. - if (tw.getTreeCount() > T_FILE && tw.getRawMode(T_FILE) == 0) + // deletion of the path. Delete what's in the working tree, + // which we know to be clean. + if (tw.getTreeCount() > T_FILE && tw.getRawMode(T_FILE) == 0) { + // Not present in working tree, so nothing to delete return true; - toBeDeleted.add(tw.getPathString()); + } + if (modeT != 0 && modeT == modeB) { + // Base, ours, and theirs all contain a folder: don't delete + return true; + } + addDeletion(tw.getPathString(), nonTree(modeO), attributes); return true; } } @@ -722,9 +809,12 @@ public class ResolveMerger extends ThreeWayMerger { result.setContainsConflicts(false); } updateIndex(base, ours, theirs, result, attributes); - if (result.containsConflicts() && !ignoreConflicts) - unmergedPaths.add(tw.getPathString()); - modifiedFiles.add(tw.getPathString()); + String currentPath = tw.getPathString(); + if (result.containsConflicts() && !ignoreConflicts) { + unmergedPaths.add(currentPath); + } + modifiedFiles.add(currentPath); + addCheckoutMetadata(currentPath, attributes); } else if (modeO != modeT) { // OURS or THEIRS has been deleted if (((modeO != 0 && !tw.idEqual(T_BASE, T_OURS)) || (modeT != 0 && !tw @@ -743,8 +833,9 @@ public class ResolveMerger extends ThreeWayMerger { if (isWorktreeDirty(work, ourDce)) return false; if (nonTree(modeT)) { - if (e != null) - toBeCheckedOut.put(tw.getPathString(), e); + if (e != null) { + addToCheckout(tw.getPathString(), e, attributes); + } } } @@ -1245,7 +1336,8 @@ public class ResolveMerger extends ThreeWayMerger { hasWorkingTreeIterator ? treeWalk.getTree(T_FILE, WorkingTreeIterator.class) : null, ignoreConflicts, hasAttributeNodeProvider - ? treeWalk.getAttributes() : new Attributes())) { + ? treeWalk.getAttributes() + : NO_ATTRIBUTES)) { cleanUp(); return false; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java index d0a5216e1e..1f4beb017f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.patch; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.encodeASCII; import static org.eclipse.jgit.util.RawParseUtils.decode; import static org.eclipse.jgit.util.RawParseUtils.decodeNoFallback; @@ -63,7 +64,6 @@ import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.diff.EditList; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AbbreviatedObjectId; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.util.QuotedString; import org.eclipse.jgit.util.RawParseUtils; @@ -198,7 +198,7 @@ public class FileHeader extends DiffEntry { * Convert the patch script for this file into a string. * <p> * The default character encoding - * ({@link org.eclipse.jgit.lib.Constants#CHARSET}) is assumed for both the + * ({@link java.nio.charset.StandardCharsets#UTF_8}) is assumed for both the * old and new files. * * @return the patch script, as a Unicode string. @@ -240,8 +240,9 @@ public class FileHeader extends DiffEntry { if (trySimpleConversion(charsetGuess)) { Charset cs = charsetGuess != null ? charsetGuess[0] : null; - if (cs == null) - cs = Constants.CHARSET; + if (cs == null) { + cs = UTF_8; + } try { return decodeNoFallback(cs, buf, startOffset, endOffset); } catch (CharacterCodingException cee) { @@ -290,8 +291,9 @@ public class FileHeader extends DiffEntry { final String[] r = new String[tmp.length]; for (int i = 0; i < tmp.length; i++) { Charset cs = csGuess != null ? csGuess[i] : null; - if (cs == null) - cs = Constants.CHARSET; + if (cs == null) { + cs = UTF_8; + } r[i] = RawParseUtils.decode(cs, tmp[i].toByteArray()); } return r; @@ -429,7 +431,7 @@ public class FileHeader extends DiffEntry { oldPath = QuotedString.GIT_PATH.dequote(buf, bol, sp - 1); oldPath = p1(oldPath); } else { - oldPath = decode(Constants.CHARSET, buf, aStart, sp - 1); + oldPath = decode(UTF_8, buf, aStart, sp - 1); } newPath = oldPath; return eol; @@ -572,7 +574,7 @@ public class FileHeader extends DiffEntry { tab--; if (ptr == tab) tab = end; - r = decode(Constants.CHARSET, buf, ptr, tab - 1); + r = decode(UTF_8, buf, ptr, tab - 1); } if (r.equals(DEV_NULL)) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java index 1dd24d732e..10ea778343 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java @@ -43,9 +43,10 @@ package org.eclipse.jgit.patch; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.util.Locale; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.util.RawParseUtils; /** @@ -120,7 +121,7 @@ public class FormatError { */ public String getLineText() { final int eol = RawParseUtils.nextLF(buf, offset); - return RawParseUtils.decode(Constants.CHARSET, buf, offset, eol); + return RawParseUtils.decode(UTF_8, buf, offset, eol); } /** {@inheritDoc} */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java index f27f356c6b..ee18fe7c2f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009, Robin Rosenberg <robin.rosenberg@dewire.com> + * Copyright (C) 2008-2018, Robin Rosenberg <robin.rosenberg@dewire.com> * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> * and other copyright owners as documented in the project's IP log. * @@ -53,6 +53,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -75,13 +76,25 @@ import org.eclipse.jgit.revwalk.RevWalk; */ public class PlotWalk extends RevWalk { + private Map<AnyObjectId, Set<Ref>> additionalRefMap; + private Map<AnyObjectId, Set<Ref>> reverseRefMap; + private Repository repository; + /** {@inheritDoc} */ @Override public void dispose() { super.dispose(); - reverseRefMap.clear(); + if (reverseRefMap != null) { + reverseRefMap.clear(); + reverseRefMap = null; + } + if (additionalRefMap != null) { + additionalRefMap.clear(); + additionalRefMap = null; + } + repository = null; } /** @@ -93,7 +106,8 @@ public class PlotWalk extends RevWalk { public PlotWalk(Repository repo) { super(repo); super.sort(RevSort.TOPO, true); - reverseRefMap = repo.getAllRefsByPeeledObjectId(); + additionalRefMap = new HashMap<>(); + repository = repo; } /** @@ -105,14 +119,14 @@ public class PlotWalk extends RevWalk { */ public void addAdditionalRefs(Iterable<Ref> refs) throws IOException { for (Ref ref : refs) { - Set<Ref> set = reverseRefMap.get(ref.getObjectId()); + Set<Ref> set = additionalRefMap.get(ref.getObjectId()); if (set == null) set = Collections.singleton(ref); else { set = new HashSet<>(set); set.add(ref); } - reverseRefMap.put(ref.getObjectId(), set); + additionalRefMap.put(ref.getObjectId(), set); } } @@ -141,11 +155,29 @@ public class PlotWalk extends RevWalk { } private Ref[] getRefs(AnyObjectId commitId) { + if (reverseRefMap == null) { + reverseRefMap = repository.getAllRefsByPeeledObjectId(); + for (Map.Entry<AnyObjectId, Set<Ref>> entry : additionalRefMap + .entrySet()) { + Set<Ref> set = reverseRefMap.get(entry.getKey()); + Set<Ref> additional = entry.getValue(); + if (set != null) { + if (additional.size() == 1) { + // It's an unmodifiable singleton set... + additional = new HashSet<>(additional); + } + additional.addAll(set); + } + reverseRefMap.put(entry.getKey(), additional); + } + additionalRefMap.clear(); + additionalRefMap = null; + } Collection<Ref> list = reverseRefMap.get(commitId); - if (list == null) + if (list == null) { return PlotCommit.NO_REFS; - else { - Ref[] tags = list.toArray(new Ref[list.size()]); + } else { + Ref[] tags = list.toArray(new Ref[0]); Arrays.sort(tags, new PlotRefComparator()); return tags; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java index b67f934f6e..86ecd8eaee 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java @@ -44,13 +44,14 @@ package org.eclipse.jgit.revwalk; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -168,10 +169,10 @@ public class RevCommit extends RevObject { } } - void parseCanonical(RevWalk walk, byte[] raw) - throws IOException { - if (!walk.shallowCommitsInitialized) - walk.initializeShallowCommits(); + void parseCanonical(RevWalk walk, byte[] raw) throws IOException { + if (!walk.shallowCommitsInitialized) { + walk.initializeShallowCommits(this); + } final MutableObjectId idBuffer = walk.idBuffer; idBuffer.fromString(raw, 5); @@ -182,13 +183,14 @@ public class RevCommit extends RevObject { RevCommit[] pList = new RevCommit[1]; int nParents = 0; for (;;) { - if (raw[ptr] != 'p') + if (raw[ptr] != 'p') { break; + } idBuffer.fromString(raw, ptr + 7); final RevCommit p = walk.lookupCommit(idBuffer); - if (nParents == 0) + if (nParents == 0) { pList[nParents++] = p; - else if (nParents == 1) { + } else if (nParents == 1) { pList = new RevCommit[] { pList[0], p }; nParents = 2; } else { @@ -218,8 +220,9 @@ public class RevCommit extends RevObject { commitTime = RawParseUtils.parseBase10(raw, ptr, null); } - if (walk.isRetainBody()) + if (walk.isRetainBody()) { buffer = raw; + } flags |= PARSED; } @@ -388,6 +391,34 @@ public class RevCommit extends RevObject { } /** + * Parse the gpg signature from the raw buffer. + * <p> + * This method parses and returns the raw content of the gpgsig lines. This + * method is fairly expensive and produces a new byte[] instance on each + * invocation. Callers should invoke this method only if they are certain + * they will need, and should cache the return value for as long as + * necessary to use all information from it. + * <p> + * RevFilter implementations should try to use + * {@link org.eclipse.jgit.util.RawParseUtils} to scan the + * {@link #getRawBuffer()} instead, as this will allow faster evaluation of + * commits. + * + * @return contents of the gpg signature; null if the commit was not signed. + * @since 5.1 + */ + public final @Nullable byte[] getRawGpgSignature() { + final byte[] raw = buffer; + final byte[] header = {'g', 'p', 'g', 's', 'i', 'g'}; + final int start = RawParseUtils.headerStart(header, raw, 0); + if (start < 0) { + return null; + } + final int end = RawParseUtils.headerEnd(raw, start); + return Arrays.copyOfRange(raw, start, end); + } + + /** * Parse the author identity from the raw buffer. * <p> * This method parses and returns the content of the author line, after @@ -539,7 +570,7 @@ public class RevCommit extends RevObject { try { return getEncoding(); } catch (IllegalCharsetNameException | UnsupportedCharsetException e) { - return CHARSET; + return UTF_8; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java index 0050bac0ae..32e7adfb0c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.revwalk; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.nio.charset.Charset; @@ -169,7 +169,7 @@ public class RevTag extends RevObject { int p = pos.value += 4; // "tag " final int nameEnd = RawParseUtils.nextLF(rawTag, p) - 1; - tagName = RawParseUtils.decode(CHARSET, rawTag, p, nameEnd); + tagName = RawParseUtils.decode(UTF_8, rawTag, p, nameEnd); if (walk.isRetainBody()) buffer = rawTag; @@ -257,7 +257,7 @@ public class RevTag extends RevObject { try { return RawParseUtils.parseEncoding(buffer); } catch (IllegalCharsetNameException | UnsupportedCharsetException e) { - return CHARSET; + return UTF_8; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index a986cfd8ff..4d555d2178 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -1460,17 +1460,44 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { lookupCommit(id).parents = RevCommit.NO_PARENTS; } - void initializeShallowCommits() throws IOException { - if (shallowCommitsInitialized) + /** + * Reads the "shallow" file and applies it by setting the parents of shallow + * commits to an empty array. + * <p> + * There is a sequencing problem if the first commit being parsed is a + * shallow commit, since {@link RevCommit#parseCanonical(RevWalk, byte[])} + * calls this method before its callers add the new commit to the + * {@link RevWalk#objects} map. That means a call from this method to + * {@link #lookupCommit(AnyObjectId)} fails to find that commit and creates + * a new one, which is promptly discarded. + * <p> + * To avoid that, {@link RevCommit#parseCanonical(RevWalk, byte[])} passes + * its commit to this method, so that this method can apply the shallow + * state to it directly and avoid creating the duplicate commit object. + * + * @param rc + * the initial commit being parsed + * @throws IOException + * if the shallow commits file can't be read + */ + void initializeShallowCommits(RevCommit rc) throws IOException { + if (shallowCommitsInitialized) { throw new IllegalStateException( JGitText.get().shallowCommitsAlreadyInitialized); + } shallowCommitsInitialized = true; - if (reader == null) + if (reader == null) { return; + } - for (ObjectId id : reader.getShallowCommits()) - lookupCommit(id).parents = RevCommit.NO_PARENTS; + for (ObjectId id : reader.getShallowCommits()) { + if (id.equals(rc.getId())) { + rc.parents = RevCommit.NO_PARENTS; + } else { + lookupCommit(id).parents = RevCommit.NO_PARENTS; + } + } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java index 4b272ba7a4..93b3baa61f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java @@ -49,7 +49,7 @@ package org.eclipse.jgit.storage.file; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.ByteArrayOutputStream; import java.io.File; @@ -166,7 +166,7 @@ public class FileBasedConfig extends StoredConfig { } else { final String decoded; if (isUtf8(in)) { - decoded = RawParseUtils.decode(CHARSET, + decoded = RawParseUtils.decode(UTF_8, in, 3, in.length); utf8Bom = true; } else { @@ -224,7 +224,7 @@ public class FileBasedConfig extends StoredConfig { bos.write(0xEF); bos.write(0xBB); bos.write(0xBF); - bos.write(text.getBytes(CHARSET)); + bos.write(text.getBytes(UTF_8)); out = bos.toByteArray(); } else { out = Constants.encode(text); 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 a0fc57ca1f..f6ec4b90eb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.ByteArrayOutputStream; import java.io.File; @@ -635,7 +635,7 @@ public class AmazonS3 { try { final Mac m = Mac.getInstance(HMAC); m.init(privateKey); - sec = Base64.encodeBytes(m.doFinal(s.toString().getBytes(CHARSET))); + sec = Base64.encodeBytes(m.doFinal(s.toString().getBytes(UTF_8))); } catch (NoSuchAlgorithmException e) { throw new IOException(MessageFormat.format(JGitText.get().noHMACsupport, HMAC, e.getMessage())); } catch (InvalidKeyException e) { 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 0dfcd8716e..ed7465c82a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -52,7 +52,6 @@ import java.text.MessageFormat; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashSet; import java.util.Set; import org.eclipse.jgit.errors.PackProtocolException; @@ -235,12 +234,12 @@ public abstract class BasePackFetchConnection extends BasePackConnection private boolean noProgress; - private Set<AnyObjectId> minimalNegotiationSet; - private String lockMessage; private PackLock packLock; + private int maxHaves; + /** RPC state, if {@link BasePackConnection#statelessRPC} is true. */ private TemporaryBuffer.Heap state; @@ -261,12 +260,12 @@ public abstract class BasePackFetchConnection extends BasePackConnection if (local != null) { final FetchConfig cfg = getFetchConfig(); allowOfsDelta = cfg.allowOfsDelta; - if (cfg.minimalNegotiation) { - minimalNegotiationSet = new HashSet<>(); - } + maxHaves = cfg.maxHaves; } else { allowOfsDelta = true; + maxHaves = Integer.MAX_VALUE; } + includeTags = transport.getTagOpt() != TagOpt.NO_TAGS; thinPack = transport.isFetchThin(); filterBlobLimit = transport.getFilterBlobLimit(); @@ -294,17 +293,16 @@ public abstract class BasePackFetchConnection extends BasePackConnection static class FetchConfig { final boolean allowOfsDelta; - final boolean minimalNegotiation; + final int maxHaves; FetchConfig(Config c) { allowOfsDelta = c.getBoolean("repack", "usedeltabaseoffset", true); //$NON-NLS-1$ //$NON-NLS-2$ - minimalNegotiation = c.getBoolean("fetch", "useminimalnegotiation", //$NON-NLS-1$ //$NON-NLS-2$ - false); + maxHaves = c.getInt("fetch", "maxhaves", Integer.MAX_VALUE); //$NON-NLS-1$ //$NON-NLS-2$ } - FetchConfig(boolean allowOfsDelta, boolean minimalNegotiation) { + FetchConfig(boolean allowOfsDelta, int maxHaves) { this.allowOfsDelta = allowOfsDelta; - this.minimalNegotiation = minimalNegotiation; + this.maxHaves = maxHaves; } } @@ -518,15 +516,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection } line.append('\n'); p.writeString(line.toString()); - if (minimalNegotiationSet != null) { - Ref current = local.exactRef(r.getName()); - if (current != null) { - ObjectId o = current.getObjectId(); - if (o != null && !o.equals(ObjectId.zeroId())) { - minimalNegotiationSet.add(o); - } - } - } } if (first) { return false; @@ -610,9 +599,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection pckOut.writeString("have " + o.name() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ havesSent++; havesSinceLastContinue++; - if (minimalNegotiationSet != null) { - minimalNegotiationSet.remove(o); - } if ((31 & havesSent) != 0) { // We group the have lines into blocks of 32, each marked @@ -646,16 +632,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection // pack on the remote side. Keep doing that. // resultsPending--; - if (minimalNegotiationSet != null - && minimalNegotiationSet.isEmpty()) { - // Minimal negotiation was requested and we sent out our - // current reference values for our wants, so terminate - // negotiation early. - if (statelessRPC) { - state.writeTo(out, null); - } - break SEND_HAVES; - } break READ_RESULT; case ACK: @@ -686,14 +662,6 @@ public abstract class BasePackFetchConnection extends BasePackConnection if (anr == AckNackResult.ACK_READY) { receivedReady = true; } - if (minimalNegotiationSet != null && minimalNegotiationSet.isEmpty()) { - // Minimal negotiation was requested and we sent out our current reference - // values for our wants, so terminate negotiation early. - if (statelessRPC) { - state.writeTo(out, null); - } - break SEND_HAVES; - } break; } @@ -709,7 +677,8 @@ public abstract class BasePackFetchConnection extends BasePackConnection state.writeTo(out, null); } - if (receivedContinue && havesSinceLastContinue > MAX_HAVES) { + if (receivedContinue && havesSinceLastContinue > MAX_HAVES + || havesSent >= maxHaves) { // Our history must be really different from the remote's. // We just sent a whole slew of have lines, and it did not // recognize any of them. Avoid sending our entire history 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 449f529447..4b20f6c8b0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java @@ -47,6 +47,8 @@ package org.eclipse.jgit.transport; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; @@ -66,7 +68,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.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; @@ -173,7 +174,7 @@ class BundleFetchConnection extends BaseFetchConnection { IO.skipFully(bin, 1); done = true; } - line.append(RawParseUtils.decode(Constants.CHARSET, hdrbuf, 0, lf)); + line.append(RawParseUtils.decode(UTF_8, hdrbuf, 0, lf)); } return line.toString(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java index f2a261bbe6..56aaede80d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java @@ -43,6 +43,8 @@ package org.eclipse.jgit.transport; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -231,7 +233,7 @@ public class BundleWriter { packWriter.setTagTargets(tagTargets); packWriter.preparePack(monitor, inc, exc); - final Writer w = new OutputStreamWriter(os, Constants.CHARSET); + final Writer w = new OutputStreamWriter(os, UTF_8); w.write(TransportBundle.V2_BUNDLE_SIGNATURE); w.write('\n'); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CapabilitiesV2Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CapabilitiesV2Request.java new file mode 100644 index 0000000000..b133ab579a --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CapabilitiesV2Request.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2018, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.transport; + +/** + * Capabilities protocol v2 request. + * + * <p> + * This is used as an input to {@link ProtocolV2Hook}. + * + * @since 5.1 + */ +public final class CapabilitiesV2Request { + private CapabilitiesV2Request() { + } + + /** @return A builder of {@link CapabilitiesV2Request}. */ + public static Builder builder() { + return new Builder(); + } + + /** A builder for {@link CapabilitiesV2Request}. */ + public static final class Builder { + private Builder() { + } + + /** @return CapabilitiesV2Request */ + public CapabilitiesV2Request build() { + return new CapabilitiesV2Request(); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProvider.java index 8115946204..f7a295d63d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProvider.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProvider.java @@ -155,7 +155,7 @@ public abstract class CredentialsProvider { */ public boolean get(URIish uri, List<CredentialItem> items) throws UnsupportedCredentialItem { - return get(uri, items.toArray(new CredentialItem[items.size()])); + return get(uri, items.toArray(new CredentialItem[0])); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java new file mode 100644 index 0000000000..853d96905c --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2018, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.transport; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.lib.ObjectId; + +/** + * fetch protocol v2 request. + * + * <p> + * This is used as an input to {@link ProtocolV2Hook}. + * + * @since 5.1 + */ +public final class FetchV2Request { + private final List<ObjectId> peerHas; + + private final TreeMap<String, ObjectId> wantedRefs; + + private final Set<ObjectId> wantsIds; + + private final Set<ObjectId> clientShallowCommits; + + private final int deepenSince; + + private final List<String> deepenNotRefs; + + private final int depth; + + private final long filterBlobLimit; + + private final Set<String> options; + + private final boolean doneReceived; + + private FetchV2Request(List<ObjectId> peerHas, + TreeMap<String, ObjectId> wantedRefs, Set<ObjectId> wantsIds, + Set<ObjectId> clientShallowCommits, int deepenSince, + List<String> deepenNotRefs, int depth, long filterBlobLimit, + boolean doneReceived, Set<String> options) { + this.peerHas = peerHas; + this.wantedRefs = wantedRefs; + this.wantsIds = wantsIds; + this.clientShallowCommits = clientShallowCommits; + this.deepenSince = deepenSince; + this.deepenNotRefs = deepenNotRefs; + this.depth = depth; + this.filterBlobLimit = filterBlobLimit; + this.doneReceived = doneReceived; + this.options = options; + } + + /** + * @return object ids in the "have" lines of the request + */ + @NonNull + List<ObjectId> getPeerHas() { + return this.peerHas; + } + + /** + * @return list of references in the "want-ref" lines of the request + */ + @NonNull + Map<String, ObjectId> getWantedRefs() { + return this.wantedRefs; + } + + /** + * @return object ids in the "want" (and "want-ref") lines of the request + */ + @NonNull + Set<ObjectId> getWantsIds() { + return wantsIds; + } + + /** + * Shallow commits the client already has. + * + * These are sent by the client in "shallow" request lines. + * + * @return set of commits the client has declared as shallow. + */ + @NonNull + Set<ObjectId> getClientShallowCommits() { + return clientShallowCommits; + } + + /** + * The value in a "deepen-since" line in the request, indicating the + * timestamp where to stop fetching/cloning. + * + * @return timestamp in seconds since the epoch, where to stop the shallow + * fetch/clone. Defaults to 0 if not set in the request. + */ + int getDeepenSince() { + return deepenSince; + } + + /** + * @return the refs in "deepen-not" lines in the request. + */ + @NonNull + List<String> getDeepenNotRefs() { + return deepenNotRefs; + } + + /** + * @return the depth set in a "deepen" line. 0 by default. + */ + int getDepth() { + return depth; + } + + /** + * @return the blob limit set in a "filter" line (-1 if not set) + */ + long getFilterBlobLimit() { + return filterBlobLimit; + } + + /** + * @return true if the request had a "done" line + */ + boolean wasDoneReceived() { + return doneReceived; + } + + /** + * Options that tune the expected response from the server, like + * "thin-pack", "no-progress" or "ofs-delta" + * + * These are options listed and well-defined in the git protocol + * specification + * + * @return options found in the request lines + */ + @NonNull + Set<String> getOptions() { + return options; + } + + /** @return A builder of {@link FetchV2Request}. */ + static Builder builder() { + return new Builder(); + } + + + /** A builder for {@link FetchV2Request}. */ + static final class Builder { + List<ObjectId> peerHas = new ArrayList<>(); + + TreeMap<String, ObjectId> wantedRefs = new TreeMap<>(); + + Set<ObjectId> wantsIds = new HashSet<>(); + + Set<ObjectId> clientShallowCommits = new HashSet<>(); + + List<String> deepenNotRefs = new ArrayList<>(); + + Set<String> options = new HashSet<>(); + + int depth; + + int deepenSince; + + long filterBlobLimit = -1; + + boolean doneReceived; + + private Builder() { + } + + /** + * @param objectId + * from a "have" line in a fetch request + * @return the builder + */ + Builder addPeerHas(ObjectId objectId) { + peerHas.add(objectId); + return this; + } + + /** + * From a "want-ref" line in a fetch request + * + * @param refName + * reference name + * @param oid + * object id + * @return the builder + */ + Builder addWantedRef(String refName, ObjectId oid) { + wantedRefs.put(refName, oid); + return this; + } + + /** + * @param option + * fetch request lines acting as options + * @return the builder + */ + Builder addOption(String option) { + options.add(option); + return this; + } + + /** + * @param objectId + * from a "want" line in a fetch request + * @return the builder + */ + Builder addWantsIds(ObjectId objectId) { + wantsIds.add(objectId); + return this; + } + + /** + * @param shallowOid + * from a "shallow" line in the fetch request + * @return the builder + */ + Builder addClientShallowCommit(ObjectId shallowOid) { + this.clientShallowCommits.add(shallowOid); + return this; + } + + /** + * @param d + * from a "deepen" line in the fetch request + * @return the builder + */ + Builder setDepth(int d) { + this.depth = d; + return this; + } + + /** + * @return depth set in the request (via a "deepen" line). Defaulting to + * 0 if not set. + */ + int getDepth() { + return this.depth; + } + + /** + * @return if there has been any "deepen not" line in the request + */ + boolean hasDeepenNotRefs() { + return !deepenNotRefs.isEmpty(); + } + + /** + * @param deepenNotRef reference in a "deepen not" line + * @return the builder + */ + Builder addDeepenNotRef(String deepenNotRef) { + this.deepenNotRefs.add(deepenNotRef); + return this; + } + + /** + * @param value + * Unix timestamp received in a "deepen since" line + * @return the builder + */ + Builder setDeepenSince(int value) { + this.deepenSince = value; + return this; + } + + /** + * @return shallow since value, sent before in a "deepen since" line. 0 + * by default. + */ + int getDeepenSince() { + return this.deepenSince; + } + + /** + * @param filterBlobLimit + * set in a "filter" line + * @return the builder + */ + Builder setFilterBlobLimit(long filterBlobLimit) { + this.filterBlobLimit = filterBlobLimit; + return this; + } + + /** + * Mark that the "done" line has been received. + * + * @return the builder + */ + Builder setDoneReceived() { + this.doneReceived = true; + return this; + } + /** + * @return Initialized fetch request + */ + FetchV2Request build() { + return new FetchV2Request(peerHas, wantedRefs, wantsIds, + clientShallowCommits, deepenSince, deepenNotRefs, + depth, filterBlobLimit, doneReceived, options); + } + } +} 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 10cd775304..760ac6c1d7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java @@ -50,7 +50,7 @@ package org.eclipse.jgit.transport; * * @since 3.2 */ -public class GitProtocolConstants { +public final class GitProtocolConstants { /** * Include tags if we are also including the referenced objects. * @@ -167,6 +167,13 @@ public class GitProtocolConstants { public static final String OPTION_FILTER = "filter"; //$NON-NLS-1$ /** + * The client specified a want-ref expression. + * + * @since 5.1 + */ + public static final String OPTION_WANT_REF = "want-ref"; //$NON-NLS-1$ + + /** * The client supports atomic pushes. If this option is used, the server * will update all refs within one atomic transaction. * @@ -231,6 +238,13 @@ public class GitProtocolConstants { public static final String CAPABILITY_PUSH_OPTIONS = "push-options"; //$NON-NLS-1$ /** + * The server supports the client specifying ref names. + * + * @since 5.1 + */ + public static final String CAPABILITY_REF_IN_WANT = "ref-in-want"; //$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/HMACSHA1NonceGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java index 1415334c63..6c26b7026a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; import static java.nio.charset.StandardCharsets.ISO_8859_1; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.File; import java.security.InvalidKeyException; @@ -102,7 +102,7 @@ public class HMACSHA1NonceGenerator implements NonceGenerator { } String input = path + ":" + String.valueOf(timestamp); //$NON-NLS-1$ - byte[] rawHmac = mac.doFinal(input.getBytes(CHARSET)); + byte[] rawHmac = mac.doFinal(input.getBytes(UTF_8)); return Long.toString(timestamp) + "-" + toHex(rawHmac); //$NON-NLS-1$ } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java index fb03190b02..69745eb310 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION; import static org.eclipse.jgit.util.HttpSupport.HDR_WWW_AUTHENTICATE; @@ -315,7 +315,7 @@ abstract class HttpAuthMethod { @Override void configureRequest(HttpConnection conn) throws IOException { String ident = user + ":" + pass; //$NON-NLS-1$ - String enc = Base64.encodeBytes(ident.getBytes(CHARSET)); + String enc = Base64.encodeBytes(ident.getBytes(UTF_8)); conn.setRequestProperty(HDR_AUTHORIZATION, type.getSchemeName() + " " + enc); //$NON-NLS-1$ } @@ -430,15 +430,15 @@ abstract class HttpAuthMethod { private static String H(String data) { MessageDigest md = newMD5(); - md.update(data.getBytes(CHARSET)); + md.update(data.getBytes(UTF_8)); return LHEX(md.digest()); } private static String KD(String secret, String data) { MessageDigest md = newMD5(); - md.update(secret.getBytes(CHARSET)); + md.update(secret.getBytes(UTF_8)); md.update((byte) ':'); - md.update(data.getBytes(CHARSET)); + md.update(data.getBytes(UTF_8)); return LHEX(md.digest()); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java index eab3b3c0cc..4e712a5567 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2018, Sasa Zivkov <sasa.zivkov@sap.com> * Copyright (C) 2016, Mark Ingram <markdingram@gmail.com> * Copyright (C) 2009, Constantine Plotnikov <constantine.plotnikov@gmail.com> * Copyright (C) 2008-2009, Google Inc. @@ -49,6 +50,10 @@ package org.eclipse.jgit.transport; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static org.eclipse.jgit.transport.OpenSshConfig.SSH_PORT; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -59,9 +64,11 @@ import java.net.ConnectException; import java.net.UnknownHostException; import java.text.MessageFormat; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; @@ -71,6 +78,8 @@ import org.slf4j.LoggerFactory; import com.jcraft.jsch.ConfigRepository; import com.jcraft.jsch.ConfigRepository.Config; +import com.jcraft.jsch.HostKey; +import com.jcraft.jsch.HostKeyRepository; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; @@ -224,6 +233,9 @@ public abstract class JschConfigSessionFactory extends SshSessionFactory { credentialsProvider)); } safeConfig(session, hc.getConfig()); + if (hc.getConfig().getValue("HostKeyAlgorithms") == null) { //$NON-NLS-1$ + setPreferredKeyTypesOrder(session); + } configure(hc, session); return session; } @@ -239,6 +251,36 @@ public abstract class JschConfigSessionFactory extends SshSessionFactory { "CheckSignatures"); //$NON-NLS-1$ } + private static void setPreferredKeyTypesOrder(Session session) { + HostKeyRepository hkr = session.getHostKeyRepository(); + List<String> known = Stream.of(hkr.getHostKey(hostName(session), null)) + .map(HostKey::getType) + .collect(toList()); + + if (!known.isEmpty()) { + String serverHostKey = "server_host_key"; //$NON-NLS-1$ + String current = session.getConfig(serverHostKey); + if (current == null) { + session.setConfig(serverHostKey, String.join(",", known)); //$NON-NLS-1$ + return; + } + + String knownFirst = Stream.concat( + known.stream(), + Stream.of(current.split(",")) //$NON-NLS-1$ + .filter(s -> !known.contains(s))) + .collect(joining(",")); //$NON-NLS-1$ + session.setConfig(serverHostKey, knownFirst); + } + } + + private static String hostName(Session s) { + if (s.getPort() == SSH_PORT) { + return s.getHost(); + } + return String.format("[%s]:%d", s.getHost(), s.getPort()); //$NON-NLS-1$ + } + private void copyConfigValueToSession(Session session, Config cfg, String from, String to) { String value = cfg.getValue(from); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java new file mode 100644 index 0000000000..3aff584a00 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2018, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.transport; + +import java.util.Collections; +import java.util.List; + +/** + * ls-refs protocol v2 request. + * + * <p> + * This is used as an input to {@link ProtocolV2Hook}. + * + * @since 5.1 + */ +public final class LsRefsV2Request { + private final List<String> refPrefixes; + + private final boolean symrefs; + + private final boolean peel; + + private LsRefsV2Request(List<String> refPrefixes, boolean symrefs, + boolean peel) { + this.refPrefixes = refPrefixes; + this.symrefs = symrefs; + this.peel = peel; + } + + /** @return ref prefixes that the client requested. */ + public List<String> getRefPrefixes() { + return refPrefixes; + } + + /** @return true if the client requests symbolic references. */ + public boolean getSymrefs() { + return symrefs; + } + + /** @return true if the client requests tags to be peeled. */ + public boolean getPeel() { + return peel; + } + + /** @return A builder of {@link LsRefsV2Request}. */ + public static Builder builder() { + return new Builder(); + } + + /** A builder for {@link LsRefsV2Request}. */ + public static final class Builder { + private List<String> refPrefixes = Collections.emptyList(); + + private boolean symrefs; + + private boolean peel; + + private Builder() { + } + + /** + * @param value + * @return the Builder + */ + public Builder setRefPrefixes(List<String> value) { + refPrefixes = value; + return this; + } + + /** + * @param value + * @return the Builder + */ + public Builder setSymrefs(boolean value) { + symrefs = value; + return this; + } + + /** + * @param value + * @return the Builder + */ + public Builder setPeel(boolean value) { + peel = value; + return this; + } + + /** @return LsRefsV2Request */ + public LsRefsV2Request build() { + return new LsRefsV2Request( + Collections.unmodifiableList(refPrefixes), symrefs, peel); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java index f5ccdc8f13..480055c2e4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java @@ -524,7 +524,7 @@ public class OpenSshConfig implements ConfigRepository { if (values == null || values.isEmpty()) { return new String[0]; } - return values.toArray(new String[values.size()]); + return values.toArray(new String[0]); } public void setValue(String key, String value) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java index cc556f8af6..c6e19d5762 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java @@ -45,13 +45,14 @@ package org.eclipse.jgit.transport; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.IOException; import java.io.InputStream; import java.text.MessageFormat; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.MutableObjectId; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; @@ -186,7 +187,7 @@ public class PacketLineIn { if (raw[len - 1] == '\n') len--; - String s = RawParseUtils.decode(Constants.CHARSET, raw, 0, len); + String s = RawParseUtils.decode(UTF_8, raw, 0, len); log.debug("git< " + s); //$NON-NLS-1$ return s; } @@ -218,7 +219,7 @@ public class PacketLineIn { IO.readFully(in, raw, 0, len); - String s = RawParseUtils.decode(Constants.CHARSET, raw, 0, len); + String s = RawParseUtils.decode(UTF_8, raw, 0, len); log.debug("git< " + s); //$NON-NLS-1$ return s; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java index a26d1d77d6..e9400919a8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java @@ -45,6 +45,8 @@ package org.eclipse.jgit.transport; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.IOException; import java.io.OutputStream; @@ -141,7 +143,7 @@ public class PacketLineOut { out.write(lenbuffer, 0, 4); out.write(buf, pos, len); if (log.isDebugEnabled()) { - String s = RawParseUtils.decode(Constants.CHARSET, buf, pos, len); + String s = RawParseUtils.decode(UTF_8, buf, pos, len); log.debug("git> " + s); //$NON-NLS-1$ } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProgressSpinner.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProgressSpinner.java index 2364434b0f..41af8078c8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProgressSpinner.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProgressSpinner.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.io.OutputStream; @@ -141,7 +141,7 @@ public class ProgressSpinner { private void write(String s) { if (write) { try { - out.write(s.getBytes(CHARSET)); + out.write(s.getBytes(UTF_8)); out.flush(); } catch (IOException e) { write = false; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Hook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Hook.java new file mode 100644 index 0000000000..d67b90b6b9 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Hook.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.transport; + +/** + * Hook to allow callers to be notified on Git protocol v2 requests. + * + * @see UploadPack#setProtocolV2Hook(ProtocolV2Hook) + * @since 5.1 + */ +public interface ProtocolV2Hook { + /** + * The default hook implementation that does nothing. + */ + static ProtocolV2Hook DEFAULT = new ProtocolV2Hook() { + // No override. + }; + + /** + * @param req + * the capabilities request + * @throws ServiceMayNotContinueException + * abort; the message will be sent to the user + * @since 5.1 + */ + default void onCapabilities(CapabilitiesV2Request req) + throws ServiceMayNotContinueException { + // Do nothing by default. + } + + /** + * @param req + * the ls-refs request + * @throws ServiceMayNotContinueException + * abort; the message will be sent to the user + * @since 5.1 + */ + default void onLsRefs(LsRefsV2Request req) + throws ServiceMayNotContinueException { + // Do nothing by default. + } + + /** + * @param req the fetch request + * @throws ServiceMayNotContinueException abort; the message will be sent to the user + */ + default void onFetch(FetchV2Request req) + throws ServiceMayNotContinueException { + // Do nothing by default + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java new file mode 100644 index 0000000000..eae2c6edb9 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2018, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.transport; + +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_DEEPEN_RELATIVE; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_FILTER; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_INCLUDE_TAG; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_NO_PROGRESS; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_OFS_DELTA; +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_WANT_REF; + +import java.io.IOException; +import java.text.MessageFormat; + +import org.eclipse.jgit.errors.PackProtocolException; +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefDatabase; + +/** + * Parse the incoming git protocol lines from the wire and translate them into a + * Request object. + * + * It requires a transferConfig object to know what the server supports (e.g. + * ref-in-want and/or filters). + */ +final class ProtocolV2Parser { + + private final TransferConfig transferConfig; + + ProtocolV2Parser(TransferConfig transferConfig) { + this.transferConfig = transferConfig; + } + + /** + * Parse the incoming fetch request arguments from the wire. The caller must + * be sure that what is comings is a fetch request before coming here. + * + * This operation requires the reference database to validate incoming + * references. + * + * @param pckIn + * incoming lines + * @param refdb + * reference database (to validate that received references exist + * and point to valid objects) + * @return A FetchV2Request populated with information received from the + * wire. + * @throws PackProtocolException + * incompatible options, wrong type of arguments or other issues + * where the request breaks the protocol. + * @throws IOException + * an IO error prevented reading the incoming message or + * accessing the ref database. + */ + FetchV2Request parseFetchRequest(PacketLineIn pckIn, RefDatabase refdb) + throws PackProtocolException, IOException { + FetchV2Request.Builder reqBuilder = FetchV2Request.builder(); + + // Packs are always sent multiplexed and using full 64K + // lengths. + reqBuilder.addOption(OPTION_SIDE_BAND_64K); + + String line; + + // Currently, we do not support any capabilities, so the next + // line is DELIM. + if ((line = pckIn.readString()) != PacketLineIn.DELIM) { + throw new PackProtocolException(MessageFormat + .format(JGitText.get().unexpectedPacketLine, line)); + } + + boolean filterReceived = false; + while ((line = pckIn.readString()) != PacketLineIn.END) { + if (line.startsWith("want ")) { //$NON-NLS-1$ + reqBuilder.addWantsIds(ObjectId.fromString(line.substring(5))); + } else if (transferConfig.isAllowRefInWant() + && line.startsWith(OPTION_WANT_REF + " ")) { //$NON-NLS-1$ + String refName = line.substring(OPTION_WANT_REF.length() + 1); + // TODO(ifrade): This validation should be done after the + // protocol parsing. It is not a protocol problem asking for an + // unexisting ref and we wouldn't need the ref database here + Ref ref = refdb.exactRef(refName); + if (ref == null) { + throw new PackProtocolException(MessageFormat + .format(JGitText.get().invalidRefName, refName)); + } + ObjectId oid = ref.getObjectId(); + if (oid == null) { + throw new PackProtocolException(MessageFormat + .format(JGitText.get().invalidRefName, refName)); + } + reqBuilder.addWantedRef(refName, oid); + reqBuilder.addWantsIds(oid); + } else if (line.startsWith("have ")) { //$NON-NLS-1$ + reqBuilder.addPeerHas(ObjectId.fromString(line.substring(5))); + } else if (line.equals("done")) { //$NON-NLS-1$ + reqBuilder.setDoneReceived(); + } else if (line.equals(OPTION_THIN_PACK)) { + reqBuilder.addOption(OPTION_THIN_PACK); + } else if (line.equals(OPTION_NO_PROGRESS)) { + reqBuilder.addOption(OPTION_NO_PROGRESS); + } else if (line.equals(OPTION_INCLUDE_TAG)) { + reqBuilder.addOption(OPTION_INCLUDE_TAG); + } else if (line.equals(OPTION_OFS_DELTA)) { + reqBuilder.addOption(OPTION_OFS_DELTA); + } else if (line.startsWith("shallow ")) { //$NON-NLS-1$ + reqBuilder.addClientShallowCommit( + ObjectId.fromString(line.substring(8))); + } else if (line.startsWith("deepen ")) { //$NON-NLS-1$ + int parsedDepth = Integer.parseInt(line.substring(7)); + if (parsedDepth <= 0) { + throw new PackProtocolException( + MessageFormat.format(JGitText.get().invalidDepth, + Integer.valueOf(parsedDepth))); + } + if (reqBuilder.getDeepenSince() != 0) { + throw new PackProtocolException( + JGitText.get().deepenSinceWithDeepen); + } + if (reqBuilder.hasDeepenNotRefs()) { + throw new PackProtocolException( + JGitText.get().deepenNotWithDeepen); + } + reqBuilder.setDepth(parsedDepth); + } else if (line.startsWith("deepen-not ")) { //$NON-NLS-1$ + reqBuilder.addDeepenNotRef(line.substring(11)); + if (reqBuilder.getDepth() != 0) { + throw new PackProtocolException( + JGitText.get().deepenNotWithDeepen); + } + } else if (line.equals(OPTION_DEEPEN_RELATIVE)) { + reqBuilder.addOption(OPTION_DEEPEN_RELATIVE); + } else if (line.startsWith("deepen-since ")) { //$NON-NLS-1$ + int ts = Integer.parseInt(line.substring(13)); + if (ts <= 0) { + throw new PackProtocolException(MessageFormat + .format(JGitText.get().invalidTimestamp, line)); + } + if (reqBuilder.getDepth() != 0) { + throw new PackProtocolException( + JGitText.get().deepenSinceWithDeepen); + } + reqBuilder.setDeepenSince(ts); + } else if (transferConfig.isAllowFilter() + && line.startsWith(OPTION_FILTER + ' ')) { + if (filterReceived) { + throw new PackProtocolException( + JGitText.get().tooManyFilters); + } + filterReceived = true; + reqBuilder.setFilterBlobLimit(filterLine( + line.substring(OPTION_FILTER.length() + 1))); + } else { + throw new PackProtocolException(MessageFormat + .format(JGitText.get().unexpectedPacketLine, line)); + } + } + + return reqBuilder.build(); + } + + /** + * Process the content of "filter" line from the protocol. It has a shape + * like "blob:none" or "blob:limit=N", with limit a positive number. + * + * @param blobLine + * the content of the "filter" line in the protocol + * @return N, the limit, defaulting to 0 if "none" + * @throws PackProtocolException + * invalid filter because due to unrecognized format or + * negative/non-numeric filter. + */ + static long filterLine(String blobLine) throws PackProtocolException { + long blobLimit = -1; + + if (blobLine.equals("blob:none")) { //$NON-NLS-1$ + blobLimit = 0; + } else if (blobLine.startsWith("blob:limit=")) { //$NON-NLS-1$ + try { + blobLimit = Long + .parseLong(blobLine.substring("blob:limit=".length())); //$NON-NLS-1$ + } catch (NumberFormatException e) { + throw new PackProtocolException(MessageFormat + .format(JGitText.get().invalidFilter, blobLine)); + } + } + /* + * We must have (1) either "blob:none" or "blob:limit=" set (because we + * only support blob size limits for now), and (2) if the latter, then + * it must be nonnegative. Throw if (1) or (2) is not met. + */ + if (blobLimit < 0) { + throw new PackProtocolException( + MessageFormat.format(JGitText.get().invalidFilter, blobLine)); + } + + return blobLimit; + } + +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java index 178c80d22e..f9fddbe889 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.util.RawParseUtils.lastIndexOfTrim; import java.text.SimpleDateFormat; @@ -95,7 +95,7 @@ public class PushCertificateIdent { */ public static PushCertificateIdent parse(String str) { MutableInteger p = new MutableInteger(); - byte[] raw = str.getBytes(CHARSET); + byte[] raw = str.getBytes(UTF_8); int tzBegin = raw.length - 1; tzBegin = lastIndexOfTrim(raw, ' ', tzBegin); if (tzBegin < 0 || raw[tzBegin] != ' ') { @@ -129,7 +129,7 @@ public class PushCertificateIdent { idEnd = raw.length; } } - String id = new String(raw, 0, idEnd, CHARSET); + String id = new String(raw, 0, idEnd, UTF_8); return new PushCertificateIdent(str, id, when * 1000L, tz); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java index 7f5a3408e3..aeca63500a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT; import static org.eclipse.jgit.lib.FileMode.TYPE_FILE; @@ -292,7 +292,8 @@ public class PushCertificateStore implements AutoCloseable { ObjectLoader loader = tw.getObjectReader().open(tw.getObjectId(0), OBJ_BLOB); try (InputStream in = loader.openStream(); - Reader r = new BufferedReader(new InputStreamReader(in, CHARSET))) { + Reader r = new BufferedReader( + new InputStreamReader(in, UTF_8))) { return PushCertificateParser.fromReader(r); } } @@ -473,7 +474,7 @@ public class PushCertificateStore implements AutoCloseable { DirCacheEditor editor = dc.editor(); String certText = pc.cert.toText() + pc.cert.getSignature(); - final ObjectId certId = inserter.insert(OBJ_BLOB, certText.getBytes(CHARSET)); + final ObjectId certId = inserter.insert(OBJ_BLOB, certText.getBytes(UTF_8)); boolean any = false; for (ReceiveCommand cmd : pc.cert.getCommands()) { if (byRef != null && !commandsEqual(cmd, byRef.get(cmd.getRefName()))) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java index dc1871b729..4662435ea7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SYMREF; @@ -74,7 +74,7 @@ import org.eclipse.jgit.lib.Repository; public abstract class RefAdvertiser { /** Advertiser which frames lines in a {@link PacketLineOut} format. */ public static class PacketLineOutRefAdvertiser extends RefAdvertiser { - private final CharsetEncoder utf8 = CHARSET.newEncoder(); + private final CharsetEncoder utf8 = UTF_8.newEncoder(); private final PacketLineOut pckOut; private byte[] binArr = new byte[256]; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java index 3100cb444a..90600cbb98 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.transport; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.transport.SideBandOutputStream.HDR_SIZE; import java.io.IOException; @@ -57,7 +58,6 @@ import java.util.regex.Pattern; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; @@ -257,6 +257,6 @@ public class SideBandInputStream extends InputStream { private String readString(int len) throws IOException { final byte[] raw = new byte[len]; IO.readFully(rawIn, raw, 0, len); - return RawParseUtils.decode(Constants.CHARSET, raw, 0, len); + return RawParseUtils.decode(UTF_8, raw, 0, len); } } 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 4ae1ccb420..6b8d5c598e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java @@ -126,6 +126,7 @@ public class TransferConfig { private final boolean allowInvalidPersonIdent; private final boolean safeForWindows; private final boolean safeForMacOS; + private final boolean allowRefInWant; private final boolean allowTipSha1InWant; private final boolean allowReachableSha1InWant; private final boolean allowFilter; @@ -180,6 +181,7 @@ public class TransferConfig { ignore.add(ObjectChecker.ErrorType.ZERO_PADDED_FILEMODE); } + allowRefInWant = rc.getBoolean("uploadpack", "allowrefinwant", false); allowTipSha1InWant = rc.getBoolean( "uploadpack", "allowtipsha1inwant", false); allowReachableSha1InWant = rc.getBoolean( @@ -262,6 +264,14 @@ public class TransferConfig { } /** + * @return true if clients are allowed to specify a "want-ref" line + * @since 5.1 + */ + public boolean isAllowRefInWant() { + return allowRefInWant; + } + + /** * Get {@link org.eclipse.jgit.transport.RefFilter} respecting configured * hidden refs. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java index d342ef46df..621c2ea56c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -46,7 +46,7 @@ package org.eclipse.jgit.transport; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.BufferedReader; import java.io.IOException; @@ -144,7 +144,7 @@ public abstract class Transport implements AutoCloseable { private static void scan(ClassLoader ldr, URL url) { try (BufferedReader br = new BufferedReader( - new InputStreamReader(url.openStream(), CHARSET))) { + new InputStreamReader(url.openStream(), UTF_8))) { String line; while ((line = br.readLine()) != null) { line = line.trim(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java index c08f400307..8b41ab0466 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -46,6 +46,7 @@ package org.eclipse.jgit.transport; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.eclipse.jgit.lib.Constants.HEAD; import static org.eclipse.jgit.util.HttpSupport.ENCODING_GZIP; import static org.eclipse.jgit.util.HttpSupport.ENCODING_X_GZIP; @@ -426,7 +427,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } private BufferedReader toBufferedReader(InputStream in) { - return new BufferedReader(new InputStreamReader(in, Constants.CHARSET)); + return new BufferedReader(new InputStreamReader(in, UTF_8)); } /** {@inheritDoc} */ @@ -483,6 +484,18 @@ public class TransportHttp extends HttpTransport implements WalkTransport, this.headers = headers; } + private NoRemoteRepositoryException createNotFoundException(URIish u, + URL url, String msg) { + String text; + if (msg != null && !msg.isEmpty()) { + text = MessageFormat.format(JGitText.get().uriNotFoundWithMessage, + url, msg); + } else { + text = MessageFormat.format(JGitText.get().uriNotFound, url); + } + return new NoRemoteRepositoryException(u, text); + } + private HttpConnection connect(String service) throws TransportException, NotSupportedException { URL u = getServiceURL(service); @@ -511,8 +524,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, return conn; case HttpConnection.HTTP_NOT_FOUND: - throw new NoRemoteRepositoryException(uri, - MessageFormat.format(JGitText.get().uriNotFound, u)); + throw createNotFoundException(uri, u, + conn.getResponseMessage()); case HttpConnection.HTTP_UNAUTHORIZED: authMethod = HttpAuthMethod.scanResponse(conn, ignoreTypes); @@ -940,7 +953,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, // Line oriented readable content is likely to compress well. // Request gzip encoding. InputStream is = open(path, AcceptEncoding.GZIP).in; - return new BufferedReader(new InputStreamReader(is, Constants.CHARSET)); + return new BufferedReader(new InputStreamReader(is, UTF_8)); } @Override @@ -1180,9 +1193,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, return; case HttpConnection.HTTP_NOT_FOUND: - throw new NoRemoteRepositoryException(uri, - MessageFormat.format(JGitText.get().uriNotFound, - conn.getURL())); + throw createNotFoundException(uri, conn.getURL(), + conn.getResponseMessage()); case HttpConnection.HTTP_FORBIDDEN: throw new TransportException(uri, 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 7de0506bb3..cd7290edcd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.transport; import static org.eclipse.jgit.lib.Constants.R_TAGS; import static org.eclipse.jgit.lib.RefDatabase.ALL; +import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REF_IN_WANT; import static org.eclipse.jgit.transport.GitProtocolConstants.COMMAND_FETCH; import static org.eclipse.jgit.transport.GitProtocolConstants.COMMAND_LS_REFS; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT; @@ -264,6 +265,9 @@ public class UploadPack { /** The refs we advertised as existing at the start of the connection. */ private Map<String, Ref> refs; + /** Hook used while processing Git protocol v2 requests. */ + private ProtocolV2Hook protocolV2Hook = ProtocolV2Hook.DEFAULT; + /** Hook used while advertising the refs to the client. */ private AdvertiseRefsHook advertiseRefsHook = AdvertiseRefsHook.DEFAULT; @@ -290,7 +294,7 @@ public class UploadPack { private final Set<RevObject> commonBase = new HashSet<>(); /** Shallow commits the client already has. */ - private final Set<ObjectId> clientShallowCommits = new HashSet<>(); + private Set<ObjectId> clientShallowCommits = new HashSet<>(); /** Desired depth from the client on a shallow request. */ private int depth; @@ -303,10 +307,10 @@ public class UploadPack { /** * (Possibly short) ref names, ancestors of which the client has asked us - * not to send using --shallow-exclude. Cannot be non-null if depth is + * not to send using --shallow-exclude. Cannot be non-empty if depth is * nonzero. */ - private @Nullable List<String> shallowExcludeRefs; + private List<String> deepenNotRefs = new ArrayList<>(); /** Commit time of the oldest common commit, in seconds. */ private int oldestTime; @@ -576,6 +580,16 @@ public class UploadPack { } /** + * Set the protocol V2 hook. + * + * @param hook + * @since 5.1 + */ + public void setProtocolV2Hook(ProtocolV2Hook hook) { + this.protocolV2Hook = hook; + } + + /** * Set the filter used while advertising the refs to the client. * <p> * Only refs allowed by this filter will be sent to the client. The filter @@ -817,7 +831,7 @@ public class UploadPack { multiAck = MultiAck.OFF; if (!clientShallowCommits.isEmpty()) - verifyClientShallow(); + verifyClientShallow(clientShallowCommits); if (depth != 0) processShallow(null, unshallowCommits, true); if (!clientShallowCommits.isEmpty()) @@ -877,25 +891,19 @@ public class UploadPack { } private void lsRefsV2() throws IOException { - PacketLineOutRefAdvertiser adv = new PacketLineOutRefAdvertiser(pckOut); - String line; - ArrayList<String> refPrefixes = new ArrayList<>(); - boolean needToFindSymrefs = false; - - adv.setUseProtocolV2(true); - - line = pckIn.readString(); - + LsRefsV2Request.Builder builder = LsRefsV2Request.builder(); + List<String> prefixes = new ArrayList<>(); + String line = pckIn.readString(); // Currently, we do not support any capabilities, so the next // line is DELIM if there are arguments or END if not. if (line == PacketLineIn.DELIM) { while ((line = pckIn.readString()) != PacketLineIn.END) { if (line.equals("peel")) { //$NON-NLS-1$ - adv.setDerefTags(true); + builder.setPeel(true); } else if (line.equals("symrefs")) { //$NON-NLS-1$ - needToFindSymrefs = true; + builder.setSymrefs(true); } else if (line.startsWith("ref-prefix ")) { //$NON-NLS-1$ - refPrefixes.add(line.substring("ref-prefix ".length())); //$NON-NLS-1$ + prefixes.add(line.substring("ref-prefix ".length())); //$NON-NLS-1$ } else { throw new PackProtocolException(MessageFormat .format(JGitText.get().unexpectedPacketLine, line)); @@ -905,21 +913,28 @@ public class UploadPack { throw new PackProtocolException(MessageFormat .format(JGitText.get().unexpectedPacketLine, line)); } - rawOut.stopBuffering(); + LsRefsV2Request req = builder.setRefPrefixes(prefixes).build(); + protocolV2Hook.onLsRefs(req); + + rawOut.stopBuffering(); + PacketLineOutRefAdvertiser adv = new PacketLineOutRefAdvertiser(pckOut); + adv.setUseProtocolV2(true); + if (req.getPeel()) { + adv.setDerefTags(true); + } Map<String, Ref> refsToSend; - if (refPrefixes.isEmpty()) { + if (req.getRefPrefixes().isEmpty()) { refsToSend = getAdvertisedOrDefaultRefs(); } else { refsToSend = new HashMap<>(); - for (String refPrefix : refPrefixes) { + for (String refPrefix : req.getRefPrefixes()) { for (Ref ref : db.getRefDatabase().getRefsByPrefix(refPrefix)) { refsToSend.put(ref.getName(), ref); } } } - - if (needToFindSymrefs) { + if (req.getSymrefs()) { findSymrefs(adv, refsToSend); } @@ -928,12 +943,6 @@ public class UploadPack { } private void fetchV2() throws IOException { - options = new HashSet<>(); - - // Packs are always sent multiplexed and using full 64K - // lengths. - options.add(OPTION_SIDE_BAND_64K); - // Depending on the requestValidator, #processHaveLines may // require that advertised be set. Set it only in the required // circumstances (to avoid a full ref lookup in the case that @@ -946,113 +955,50 @@ public class UploadPack { advertised = refIdSet(getAdvertisedOrDefaultRefs().values()); } - String line; - List<ObjectId> peerHas = new ArrayList<>(); - boolean doneReceived = false; + ProtocolV2Parser parser = new ProtocolV2Parser(transferConfig); + FetchV2Request req = parser.parseFetchRequest(pckIn, + db.getRefDatabase()); + rawOut.stopBuffering(); - // Currently, we do not support any capabilities, so the next - // line is DELIM. - if ((line = pckIn.readString()) != PacketLineIn.DELIM) { - throw new PackProtocolException(MessageFormat - .format(JGitText.get().unexpectedPacketLine, line)); - } + protocolV2Hook.onFetch(req); - boolean includeTag = false; - boolean filterReceived = false; - while ((line = pckIn.readString()) != PacketLineIn.END) { - if (line.startsWith("want ")) { //$NON-NLS-1$ - wantIds.add(ObjectId.fromString(line.substring(5))); - } else if (line.startsWith("have ")) { //$NON-NLS-1$ - peerHas.add(ObjectId.fromString(line.substring(5))); - } else if (line.equals("done")) { //$NON-NLS-1$ - doneReceived = true; - } else if (line.equals(OPTION_THIN_PACK)) { - options.add(OPTION_THIN_PACK); - } else if (line.equals(OPTION_NO_PROGRESS)) { - options.add(OPTION_NO_PROGRESS); - } else if (line.equals(OPTION_INCLUDE_TAG)) { - options.add(OPTION_INCLUDE_TAG); - includeTag = true; - } else if (line.equals(OPTION_OFS_DELTA)) { - options.add(OPTION_OFS_DELTA); - } else if (line.startsWith("shallow ")) { //$NON-NLS-1$ - clientShallowCommits.add(ObjectId.fromString(line.substring(8))); - } else if (line.startsWith("deepen ")) { //$NON-NLS-1$ - depth = Integer.parseInt(line.substring(7)); - if (depth <= 0) { - throw new PackProtocolException( - MessageFormat.format(JGitText.get().invalidDepth, - Integer.valueOf(depth))); - } - if (shallowSince != 0) { - throw new PackProtocolException( - JGitText.get().deepenSinceWithDeepen); - } - if (shallowExcludeRefs != null) { - throw new PackProtocolException( - JGitText.get().deepenNotWithDeepen); - } - } else if (line.startsWith("deepen-not ")) { //$NON-NLS-1$ - List<String> exclude = shallowExcludeRefs; - if (exclude == null) { - exclude = shallowExcludeRefs = new ArrayList<>(); - } - exclude.add(line.substring(11)); - if (depth != 0) { - throw new PackProtocolException( - JGitText.get().deepenNotWithDeepen); - } - } else if (line.equals(OPTION_DEEPEN_RELATIVE)) { - options.add(OPTION_DEEPEN_RELATIVE); - } else if (line.startsWith("deepen-since ")) { //$NON-NLS-1$ - shallowSince = Integer.parseInt(line.substring(13)); - if (shallowSince <= 0) { - throw new PackProtocolException( - MessageFormat.format( - JGitText.get().invalidTimestamp, line)); - } - if (depth != 0) { - throw new PackProtocolException( - JGitText.get().deepenSinceWithDeepen); - } - } else if (transferConfig.isAllowFilter() - && line.startsWith(OPTION_FILTER + ' ')) { - if (filterReceived) { - throw new PackProtocolException(JGitText.get().tooManyFilters); - } - filterReceived = true; - parseFilter(line.substring(OPTION_FILTER.length() + 1)); - } else { - throw new PackProtocolException(MessageFormat - .format(JGitText.get().unexpectedPacketLine, line)); - } - } - rawOut.stopBuffering(); + // TODO(ifrade): Refactor to pass around the Request object, instead of + // copying data back to class fields + options = req.getOptions(); + wantIds.addAll(req.getWantsIds()); + clientShallowCommits = req.getClientShallowCommits(); + depth = req.getDepth(); + shallowSince = req.getDeepenSince(); + filterBlobLimit = req.getFilterBlobLimit(); + deepenNotRefs = req.getDeepenNotRefs(); boolean sectionSent = false; @Nullable List<ObjectId> shallowCommits = null; List<ObjectId> unshallowCommits = new ArrayList<>(); - if (!clientShallowCommits.isEmpty()) { - verifyClientShallow(); + if (!req.getClientShallowCommits().isEmpty()) { + verifyClientShallow(req.getClientShallowCommits()); } - if (depth != 0 || shallowSince != 0 || shallowExcludeRefs != null) { - shallowCommits = new ArrayList<ObjectId>(); + if (req.getDepth() != 0 || req.getDeepenSince() != 0 + || !req.getDeepenNotRefs().isEmpty()) { + shallowCommits = new ArrayList<>(); processShallow(shallowCommits, unshallowCommits, false); } - if (!clientShallowCommits.isEmpty()) - walk.assumeShallow(clientShallowCommits); + if (!req.getClientShallowCommits().isEmpty()) + walk.assumeShallow(req.getClientShallowCommits()); - if (doneReceived) { - processHaveLines(peerHas, ObjectId.zeroId(), new PacketLineOut(NullOutputStream.INSTANCE)); + if (req.wasDoneReceived()) { + processHaveLines(req.getPeerHas(), ObjectId.zeroId(), + new PacketLineOut(NullOutputStream.INSTANCE)); } else { pckOut.writeString("acknowledgments\n"); //$NON-NLS-1$ - for (ObjectId id : peerHas) { + for (ObjectId id : req.getPeerHas()) { if (walk.getObjectReader().has(id)) { pckOut.writeString("ACK " + id.getName() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ } } - processHaveLines(peerHas, ObjectId.zeroId(), new PacketLineOut(NullOutputStream.INSTANCE)); + processHaveLines(req.getPeerHas(), ObjectId.zeroId(), + new PacketLineOut(NullOutputStream.INSTANCE)); if (okToGiveUp()) { pckOut.writeString("ready\n"); //$NON-NLS-1$ } else if (commonBase.isEmpty()) { @@ -1061,7 +1007,7 @@ public class UploadPack { sectionSent = true; } - if (doneReceived || okToGiveUp()) { + if (req.wasDoneReceived() || okToGiveUp()) { if (shallowCommits != null) { if (sectionSent) pckOut.writeDelim(); @@ -1075,16 +1021,33 @@ public class UploadPack { sectionSent = true; } + if (!req.getWantedRefs().isEmpty()) { + if (sectionSent) { + pckOut.writeDelim(); + } + pckOut.writeString("wanted-refs\n"); //$NON-NLS-1$ + for (Map.Entry<String, ObjectId> entry : req.getWantedRefs() + .entrySet()) { + pckOut.writeString(entry.getValue().getName() + ' ' + + entry.getKey() + '\n'); + } + sectionSent = true; + } + if (sectionSent) pckOut.writeDelim(); pckOut.writeString("packfile\n"); //$NON-NLS-1$ sendPack(new PackStatistics.Accumulator(), - includeTag + req.getOptions().contains(OPTION_INCLUDE_TAG) ? db.getRefDatabase().getRefsByPrefix(R_TAGS) : null, unshallowCommits); + // sendPack invokes pckOut.end() for us, so we do not + // need to invoke it here. + } else { + // Invoke pckOut.end() by ourselves. + pckOut.end(); } - pckOut.end(); } /* @@ -1121,9 +1084,13 @@ public class UploadPack { ArrayList<String> caps = new ArrayList<>(); caps.add("version 2"); //$NON-NLS-1$ caps.add(COMMAND_LS_REFS); + boolean advertiseRefInWant = transferConfig.isAllowRefInWant() && + db.getConfig().getBoolean("uploadpack", null, //$NON-NLS-1$ + "advertiserefinwant", true); //$NON-NLS-1$ caps.add( COMMAND_FETCH + '=' + (transferConfig.isAllowFilter() ? OPTION_FILTER + ' ' : "") + //$NON-NLS-1$ + (advertiseRefInWant ? CAPABILITY_REF_IN_WANT + ' ' : "") + //$NON-NLS-1$ OPTION_SHALLOW); return caps; } @@ -1134,6 +1101,8 @@ public class UploadPack { // is sent only if this is a bidirectional pipe. (If // not, the client is expected to call // sendAdvertisedRefs() on its own.) + protocolV2Hook + .onCapabilities(CapabilitiesV2Request.builder().build()); for (String s : getV2CapabilityAdvertisement()) { pckOut.writeString(s + "\n"); //$NON-NLS-1$ } @@ -1181,7 +1150,7 @@ public class UploadPack { boolean writeToPckOut) throws IOException { if (options.contains(OPTION_DEEPEN_RELATIVE) || shallowSince != 0 || - shallowExcludeRefs != null) { + !deepenNotRefs.isEmpty()) { // TODO(jonathantanmy): Implement deepen-relative, deepen-since, // and deepen-not. throw new UnsupportedOperationException(); @@ -1232,9 +1201,14 @@ public class UploadPack { } } - private void verifyClientShallow() + /* + * Verify all shallow lines refer to commits + * + * It can mutate the input set (removing missing object ids from it) + */ + private void verifyClientShallow(Set<ObjectId> shallowCommits) throws IOException, PackProtocolException { - AsyncRevObjectQueue q = walk.parseAny(clientShallowCommits, true); + AsyncRevObjectQueue q = walk.parseAny(shallowCommits, true); try { for (;;) { try { @@ -1252,7 +1226,7 @@ public class UploadPack { } catch (MissingObjectException notCommit) { // shallow objects not known at the server are ignored // by git-core upload-pack, match that behavior. - clientShallowCommits.remove(notCommit.getObjectId()); + shallowCommits.remove(notCommit.getObjectId()); continue; } } @@ -1298,6 +1272,8 @@ public class UploadPack { if (useProtocolV2()) { // The equivalent in v2 is only the capabilities // advertisement. + protocolV2Hook + .onCapabilities(CapabilitiesV2Request.builder().build()); for (String s : getV2CapabilityAdvertisement()) { adv.writeOne(s); } @@ -1382,33 +1358,6 @@ public class UploadPack { return msgOut; } - private void parseFilter(String arg) throws PackProtocolException { - if (arg.equals("blob:none")) { //$NON-NLS-1$ - filterBlobLimit = 0; - } else if (arg.startsWith("blob:limit=")) { //$NON-NLS-1$ - try { - filterBlobLimit = Long.parseLong( - arg.substring("blob:limit=".length())); //$NON-NLS-1$ - } catch (NumberFormatException e) { - throw new PackProtocolException( - MessageFormat.format(JGitText.get().invalidFilter, - arg)); - } - } - /* - * We must have (1) either "blob:none" or - * "blob:limit=" set (because we only support - * blob size limits for now), and (2) if the - * latter, then it must be nonnegative. Throw - * if (1) or (2) is not met. - */ - if (filterBlobLimit < 0) { - throw new PackProtocolException( - MessageFormat.format(JGitText.get().invalidFilter, - arg)); - } - } - private void recvWants() throws IOException { boolean isFirst = true; boolean filterReceived = false; @@ -1449,7 +1398,7 @@ public class UploadPack { } filterReceived = true; - parseFilter(arg); + filterBlobLimit = ProtocolV2Parser.filterLine(arg); continue; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java index aa71c9445a..6d4df4fbad 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java @@ -43,6 +43,8 @@ package org.eclipse.jgit.transport; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; @@ -363,7 +365,7 @@ abstract class WalkRemoteObjectDatabase { */ BufferedReader openReader(String path) throws IOException { final InputStream is = open(path).in; - return new BufferedReader(new InputStreamReader(is, Constants.CHARSET)); + return new BufferedReader(new InputStreamReader(is, UTF_8)); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java index 470ed02841..335abe1b5b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java @@ -45,6 +45,8 @@ package org.eclipse.jgit.treewalk; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; @@ -182,7 +184,7 @@ public abstract class AbstractTreeIterator { if (prefix != null && prefix.length() > 0) { final ByteBuffer b; - b = Constants.CHARSET.encode(CharBuffer.wrap(prefix)); + b = UTF_8.encode(CharBuffer.wrap(prefix)); pathLen = b.limit(); path = new byte[Math.max(DEFAULT_PATH_SIZE, pathLen + 1)]; b.get(path, 0, pathLen); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java index d500aae681..69303d6ee3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java @@ -44,10 +44,13 @@ package org.eclipse.jgit.treewalk; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.errors.JGitInternalException; @@ -1045,7 +1048,7 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { final AbstractTreeIterator t = currentHead; final int off = t.pathOffset; final int end = t.pathLen; - return RawParseUtils.decode(Constants.CHARSET, t.path, off, end); + return RawParseUtils.decode(UTF_8, t.path, off, end); } /** @@ -1378,11 +1381,11 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { } static String pathOf(AbstractTreeIterator t) { - return RawParseUtils.decode(Constants.CHARSET, t.path, 0, t.pathLen); + return RawParseUtils.decode(UTF_8, t.path, 0, t.pathLen); } static String pathOf(byte[] buf, int pos, int end) { - return RawParseUtils.decode(Constants.CHARSET, buf, pos, end); + return RawParseUtils.decode(UTF_8, buf, pos, end); } /** @@ -1436,7 +1439,8 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { return null; } return filterCommand.replaceAll("%f", //$NON-NLS-1$ - QuotedString.BOURNE.quote((getPathString()))); + Matcher.quoteReplacement( + QuotedString.BOURNE.quote((getPathString())))); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index 179fd46791..7c6bfb9d63 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -46,6 +46,8 @@ package org.eclipse.jgit.treewalk; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; @@ -1413,7 +1415,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { IteratorState(WorkingTreeOptions options) { this.options = options; - this.nameEncoder = Constants.CHARSET.newEncoder(); + this.nameEncoder = UTF_8.newEncoder(); } void initializeReadBuffer() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java index 442f0793fb..69f8547452 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java @@ -6,7 +6,7 @@ package org.eclipse.jgit.util; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.text.MessageFormat; import java.util.Arrays; @@ -54,7 +54,7 @@ public class Base64 { + "abcdefghijklmnopqrstuvwxyz" // //$NON-NLS-1$ + "0123456789" // //$NON-NLS-1$ + "+/" // //$NON-NLS-1$ - ).getBytes(CHARSET); + ).getBytes(UTF_8); DEC = new byte[128]; Arrays.fill(DEC, INVALID_DEC); @@ -177,7 +177,7 @@ public class Base64 { e += 4; } - return new String(outBuff, 0, e, CHARSET); + return new String(outBuff, 0, e, UTF_8); } /** @@ -293,7 +293,7 @@ public class Base64 { * @return the decoded data */ public static byte[] decode(String s) { - byte[] bytes = s.getBytes(CHARSET); + byte[] bytes = s.getBytes(UTF_8); return decode(bytes, 0, bytes.length); } } 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 8948e6099a..e5c2922cfa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -640,12 +640,15 @@ public abstract class FS { JGitText.get().commandClosedStderrButDidntExit, desc, PROCESS_EXIT_TIMEOUT), -1); fail.set(true); + return false; } } catch (InterruptedException e) { - LOG.error(MessageFormat.format( - JGitText.get().threadInterruptedWhileRunning, desc), e); + setError(originalError, MessageFormat.format( + JGitText.get().threadInterruptedWhileRunning, desc), -1); + fail.set(true); + return false; } - return false; + return true; } private void setError(IOException e, String message, int exitCode) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java index 9f99e28557..98797dc64f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java @@ -169,7 +169,7 @@ public class FS_Win32 extends FS { if (result.isEmpty()) { return NO_ENTRIES; } - return result.toArray(new Entry[result.size()]); + return result.toArray(new Entry[0]); } /** {@inheritDoc} */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java index 3393fbfd1d..e5c8d9d398 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java @@ -43,7 +43,7 @@ package org.eclipse.jgit.util; -import static org.eclipse.jgit.lib.Constants.CHARSET; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.File; import java.io.PrintStream; @@ -126,7 +126,7 @@ public class FS_Win32_Cygwin extends FS_Win32 { try { w = readPipe(dir, // new String[] { cygpath, "--windows", "--absolute", pn }, // //$NON-NLS-1$ //$NON-NLS-2$ - CHARSET.name()); + UTF_8.name()); } catch (CommandFailedException e) { LOG.warn(e.getMessage()); return null; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java index 2f547c15b0..ecfd31647d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java @@ -45,6 +45,8 @@ package org.eclipse.jgit.util; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.File; import java.io.IOException; import java.nio.file.AtomicMoveNotSupportedException; @@ -712,7 +714,7 @@ public class FileUtils { Path nioPath = toPath(file); if (Files.isSymbolicLink(nioPath)) return Files.readSymbolicLink(nioPath).toString() - .getBytes(Constants.CHARSET).length; + .getBytes(UTF_8).length; return Files.size(nioPath); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/QuotedString.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/QuotedString.java index 4d58d0614a..a55cad3705 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/QuotedString.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/QuotedString.java @@ -43,6 +43,8 @@ package org.eclipse.jgit.util; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.util.Arrays; import org.eclipse.jgit.lib.Constants; @@ -181,7 +183,7 @@ public abstract class QuotedString { continue; } } - return RawParseUtils.decode(Constants.CHARSET, r, 0, rPtr); + return RawParseUtils.decode(UTF_8, r, 0, rPtr); } } @@ -294,7 +296,7 @@ public abstract class QuotedString { public String dequote(byte[] in, int inPtr, int inEnd) { if (2 <= inEnd - inPtr && in[inPtr] == '"' && in[inEnd - 1] == '"') return dq(in, inPtr + 1, inEnd - 1); - return RawParseUtils.decode(Constants.CHARSET, in, inPtr, inEnd); + return RawParseUtils.decode(UTF_8, in, inPtr, inEnd); } private static String dq(byte[] in, int inPtr, int inEnd) { @@ -370,7 +372,7 @@ public abstract class QuotedString { } } - return RawParseUtils.decode(Constants.CHARSET, r, 0, rPtr); + return RawParseUtils.decode(UTF_8, r, 0, rPtr); } private GitPathStyle() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java index c22c8de5d1..28f406a49e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java @@ -549,6 +549,62 @@ public final class RawParseUtils { } /** + * Locate the end of the header. Note that headers may be + * more than one line long. + * @param b + * buffer to scan. + * @param ptr + * position within buffer to start looking for the end-of-header. + * @return new position just after the header. This is either + * b.length, or the index of the header's terminating newline. + * @since 5.1 + */ + public static final int headerEnd(final byte[] b, int ptr) { + final int sz = b.length; + while (ptr < sz) { + final byte c = b[ptr++]; + if (c == '\n' && (ptr == sz || b[ptr] != ' ')) { + return ptr - 1; + } + } + return ptr - 1; + } + + /** + * Find the start of the contents of a given header. + * + * @param b + * buffer to scan. + * @param headerName + * header to search for + * @param ptr + * position within buffer to start looking for header at. + * @return new position at the start of the header's contents, -1 for + * not found + * @since 5.1 + */ + public static final int headerStart(byte[] headerName, byte[] b, int ptr) { + // Start by advancing to just past a LF or buffer start + if (ptr != 0) { + ptr = nextLF(b, ptr - 1); + } + while (ptr < b.length - (headerName.length + 1)) { + boolean found = true; + for (int i = 0; i < headerName.length; i++) { + if (headerName[i] != b[ptr++]) { + found = false; + break; + } + } + if (found && b[ptr++] == ' ') { + return ptr; + } + ptr = nextLF(b, ptr); + } + return -1; + } + + /** * Locate the first position before a given character. * * @param b diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/MessageWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/MessageWriter.java index 94e5ef3d74..12d809b513 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/MessageWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/MessageWriter.java @@ -43,13 +43,14 @@ package org.eclipse.jgit.util.io; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.util.RawParseUtils; /** @@ -80,7 +81,7 @@ public class MessageWriter extends Writer { */ public MessageWriter() { buf = new ByteArrayOutputStream(); - enc = new OutputStreamWriter(getRawStream(), Constants.CHARSET); + enc = new OutputStreamWriter(getRawStream(), UTF_8); } /** {@inheritDoc} */ @@ -51,7 +51,7 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> <packaging>pom</packaging> - <version>5.0.4-SNAPSHOT</version> + <version>5.1.3-SNAPSHOT</version> <name>JGit - Parent</name> <url>${jgit-url}</url> @@ -207,17 +207,18 @@ <commons-compress-version>1.15</commons-compress-version> <osgi-core-version>4.3.1</osgi-core-version> <servlet-api-version>3.1.0</servlet-api-version> - <jetty-version>9.4.8.v20171121</jetty-version> - <japicmp-version>0.11.0</japicmp-version> - <httpclient-version>4.5.2</httpclient-version> - <httpcore-version>4.4.6</httpcore-version> + <jetty-version>9.4.11.v20180605</jetty-version> + <japicmp-version>0.13.0</japicmp-version> + <httpclient-version>4.5.5</httpclient-version> + <httpcore-version>4.4.9</httpcore-version> <slf4j-version>1.7.2</slf4j-version> <log4j-version>1.2.15</log4j-version> <maven-javadoc-plugin-version>3.0.1</maven-javadoc-plugin-version> - <tycho-extras-version>1.1.0</tycho-extras-version> + <tycho-extras-version>1.2.0</tycho-extras-version> <gson-version>2.8.2</gson-version> - <spotbugs-maven-plugin-version>3.1.2</spotbugs-maven-plugin-version> - <maven-surefire-report-plugin-version>2.20.1</maven-surefire-report-plugin-version> + <spotbugs-maven-plugin-version>3.1.6</spotbugs-maven-plugin-version> + <maven-surefire-report-plugin-version>2.21.0</maven-surefire-report-plugin-version> + <maven-compiler-plugin-version>3.8.0</maven-compiler-plugin-version> <!-- Properties to enable jacoco code coverage analysis --> <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin> @@ -249,7 +250,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>3.0.2</version> + <version>3.1.0</version> <configuration> <archive> <manifestEntries> @@ -268,13 +269,13 @@ <plugin> <artifactId>maven-clean-plugin</artifactId> - <version>3.0.0</version> + <version>3.1.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> - <version>3.1.0</version> + <version>3.1.1</version> </plugin> <plugin> @@ -304,7 +305,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> - <version>2.20.1</version> + <version>2.21.0</version> <configuration> <forkCount>${test-fork-count}</forkCount> <reuseForks>true</reuseForks> @@ -337,7 +338,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> - <version>3.8</version> + <version>3.10.0</version> <configuration> <sourceEncoding>utf-8</sourceEncoding> <minimumTokens>100</minimumTokens> @@ -360,7 +361,7 @@ <plugin> <groupId>org.eclipse.cbi.maven.plugins</groupId> <artifactId>eclipse-jarsigner-plugin</artifactId> - <version>1.1.4</version> + <version>1.1.5</version> </plugin> <plugin> <groupId>org.eclipse.tycho.extras</groupId> @@ -375,17 +376,17 @@ <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.7.9</version> + <version>0.8.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> - <version>3.6</version> + <version>3.7.1</version> <dependencies> <dependency><!-- add support for ssh/scp --> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> - <version>2.12</version> + <version>3.1.0</version> </dependency> </dependencies> </plugin> @@ -744,7 +745,7 @@ <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> - <version>3.7.0</version> + <version>${maven-compiler-plugin-version}</version> <configuration> <encoding>UTF-8</encoding> <source>1.8</source> @@ -772,6 +773,9 @@ <configuration> <compilerId>javac-with-errorprone</compilerId> <forceJavacCompilerUse>true</forceJavacCompilerUse> + <compilerArgs> + <arg>-Xep:ExpectedExceptionChecker:ERROR</arg> + </compilerArgs> <excludes> <exclude>org/eclipse/jgit/transport/InsecureCipherFactory.java</exclude> </excludes> @@ -782,7 +786,7 @@ <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-compiler-javac</artifactId> - <version>2.8.2</version> + <version>2.8.4</version> </dependency> <dependency> <groupId>org.codehaus.plexus</groupId> @@ -810,7 +814,7 @@ <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> - <version>3.7.0</version> + <version>${maven-compiler-plugin-version}</version> <configuration> <compilerId>eclipse</compilerId> <encoding>UTF-8</encoding> |